.net core на linux, devops на коне

Меняю свой стек с понедельника

Приветствую, коллега!
Примерно за год до момента написания этой статьи мне начало казаться, что я начал выгорать. Работа, уже давно превратившаяся в ремесло, перестала приносить то студенческое чувство первооткрытия, знакомое каждому программисту, приносящее эйфорию. Ради этого чувства, ради новых знаний я когда-то просиживал за монитором по 18 часов в сутки. Это давно прошло… но недавно я испытал это чувство снова! Сначала оно было тихим, непривычным из-за длительного перерыва, но со временем оно разгорелось и заполыхало!
Если вы такой же, как и я, программист со стажем около от 12 лет, возрастом в районе 30 лет, задержавшийся в своем родном стойле стеке (особенно если это C# .Net MVC), то приглашаю под кат. Тем, кто моложе — думаю тоже будет полезно, чтобы заранее быть готовыми.

What’s covered

.NET Core refers to several technologies including .NET Core, ASP.NET Core and Entity Framework Core.

Looking for the support policy for another part of the .NET platform? See .NET Support Policy.

Every Microsoft product has a lifecycle. The lifecycle begins when a product is released and ends when it’s no longer supported. Knowing key dates in this lifecycle helps you make informed decisions about when to upgrade or make other changes to your software. This product is governed by Microsoft’s Modern Lifecycle Policy.

The .NET Core support lifecycle offers support for each release. The length of time and degree of support vary based on a few qualifications.

What releases qualify for servicing and how do updates effect servicing qualifications?

Customers can choose Long Term Support (LTS) releases or Current releases. LTS releases will receive only critical and compatible fixes throughout their lifecycle. Current releases will receive these same fixes and will also be updated with compatible innovations and features.

Within a release’s support lifecycle, systems must remain current on released patch updates.

Битва C# JSON сериализаторов для .NET Core 3

Перевод

Недавно выпущенный .NET Core 3 принес с собой ряд нововведений. Помимо C# 8 и поддержки WinForms и WPF, в последнем релизе был добавлен новый JSON (де)сериализатор — System.Text.Json, и, как следует из его названия, все его классы находятся в этом пространстве имен.
Это серьезное нововведение. Сериализация JSON — важный фактор в веб-приложениях. На нее полагается большая часть сегодняшнего REST API. Когда ваш javascript клиент отправляет JSON в теле POST запроса, сервер использует десериализацию JSON для преобразования его в C# объект. И когда сервер возвращает в ответ объект, он сериализует этот объект в JSON, чтобы ваш javascript клиент мог его понять. Это большие операции, которые выполняются для каждого запроса с объектами. Их производительность может значительно повлиять на производительность приложений, что я и собираюсь сейчас продемонстрировать.

Middleware

В ASP.NET существует определенная цепочка вызовов кода, которая происходит при каждом request. Еще до того, как загрузился UI/MVC выполняются определенные действия.

То есть, например, если мы добавим в начало метода Configure класса Startup.cs код

то мы сможем посмотреть в консоли дебага какие файлы запрашивает наше приложение. Фактически мы получаем возможности AOP “out of box”
Немного useless, но понятный и познавательный пример использования middleware я вам сейчас покажу:

При каждом запросе начинает выполнятся цепочка вызовов. Из каждого app.Use после вызова next.invoke() совершается переход ко следующему вызову. И все завершается после того как отработает app.Run.
Можно выполнять какой-то код только при обращении к определенному route.
Сделать это можно с помощью app.Map:

Теперь если просто перейти на страницу сайта, то можно будет увидеть текст “Hello!”, а если добавить к строке адреса /Goodbye, то вам будет отображено Goodbye.

Кроме Use и Map можно использовать UseWhen или MapWhen для того, чтобы добавлять код в цепочку middleware только при каких-то определенных условиях.

До сих пор были все еще useless примеры, правда? Вот вам нормальный пример:

Здесь мы добавляем к каждому запросу заголовки, помогающие обезопасить страницу от хакерских атак.

Или же вот пример локализации:

Теперь если вы к адресу страницы добавите параметр ?culture=fr то вы сможете переключить язык приложения на французский (если в ваше приложение добавлена локализация, то все сработает)

What’s the catch?

Okay, there is a catch. For now. When you create a standalone application using the dotnet publish command, your DLL is placed into the target directory along with all of the .NET bits necessary to run your DLL. That is, you may see 50 files in the directory. This is going to change soon. An already-running-in-the-lab initiative, .NET Native, will soon be introduced with a future release of .NET Core. This will build one executable with all the bits included. It’s just like when you are compiling in the Go language, where you specify the target platform and you get one executable; .NET will do that as well.

You do need to build once for each target, which only makes sense. You simply include a runtime identifier and build the code, like this example, which builds the release version for RHEL 7.x on a 64-bit processor:

Установка

Устанавливать среду выполнения вручную нужно только в тех случаях, когда версия на вашем ПК устарела и не позволяет запускать нужные пользователю программы. Обновляется автоматически, с помощью обновлений Windows, но вручную вы можете установить версии 4.x в Windows 7.

Скачайте .NET Framework с сайта Майкрософт.

Какие версии .NET Framework применяют в 2019 году

На 14 декабря 2019 года для загрузки предлагаются следующие версии:

  • 4.8
  • 4.7.2
  • 4.7.1
  • 4.7
  • 4.6.2
  • 4.6.1
  • 4.6
  • 4.5.2
  • 4.5.1
  • 4.5
  • 4.0
  • 3.5 SP1

Майкрософт рекомендует использовать самую свежую версию платформы.

Пользователям, не занимающимся созданием ПО, понадобится среда выполнения (Runtime). Инструментарий разработчика (Developer Pack) необходим программистам.

Прокрутите страницу. Выберите язык и перейдите по соответствующей ссылке. Скачивание стартует автоматически.

.NET Framework 3.5 в Windows 10

Перед установкой на ноутбук убедитесь, что батарея заряжена и подключен кабель питания.

Скачайте 3.5 SP1. Запустите загруженный исполняемый файл с расширением EXE. Чтобы началась установка, пользователю придется позволить ПО вносить изменения на компьютере.

Необходимо дополнительно загрузить и поставить в систему .NET 3.5 (в комплекте: .NET 2.0 и 3.0).

На экране отображается прогресс выполнения загрузки, время которой зависит от скорости интернет-соединения.

Следующий этап — установка компонентов операционной системы осуществляется автоматически. Не требует вмешательства пользователя.

Для завершения установки нужно перезагрузить компьютер. Нажмите соответствующую кнопку (выделена на иллюстрации).

Не выключайте компьютер во время работы с обновлениями. Прогресс выполнения задачи динамически отображается на экране (в процентах).

Чтобы включить поддержку версии 3.5 в «десятке»:

  • Нажмите кнопку со значком-лупой на Панели задач
  • В строке напечатайте: «Включение или отключение компонентов Windows»
  • Щелкните по выведенному в качестве результата поиска параметру Панели управления

Щелчком мыши включите компонент, если его поддержка отключена. Отключено: белый квадрат слева от названия пуст. Включено: в нем располагается черный квадратик.

Обратите внимание, что поддержка версии 3.5, необходимой для совместимости со старым софтом, является дополнением к версии 4.x. Нажмите «OK»

Нажмите «OK».

Что нового дает переход на .NET Core 3.1

Generic Host

В .NET Core 2.1 Generic Host является неким дополнением к Web Host, это позволяет использовать такие инструменты, как внедрение зависимостей (DI) и протоколирование абстракций. В .NET Core 3.х был сделан акцент на большую совместимость с Generic Host, теперь вы можете использовать обновленный Generic Host Builder вместо Web Host Builder. Это дает возможность создавать любые приложения, начиная от консольных приложений и WPF и заканчивая веб-приложениями на одной базовой хостинговой парадигме с одинаковыми общими абстракциями.

Вы все еще можете продолжать использовать WebHostBuilder, но необходимо понимать что некоторые типы устарели в ASP.NET Core 3.1, и могут быть заменены в следующей версии.

global.json

Теперь вы можете указать версию, начиная с которой можно без проблем производить сборку приложения, без необходимости каждый раз вносить правки в global.json после выхода очередного патча. Тем самым определяя тот функциональный диапазон, который нужен исходя из ваших требований. Также это даст вам гарантию того, что пользователи вашего приложения будут запускать его именно на тех сборках SDK которые вы определили, а не последней версии, которая установлена на сервере.

ASP.NET Core Module V2

До .NET Core 2.2 IIS по умолчанию размещал приложение .NET Core, выполняя экземпляр Kestrel (встроенный веб-сервер .NET Core) и перенаправляя запросы из IIS в Kestrel. В основном IIS действовал как прокси. Это работает, но медленно, так как выполняется двойной переход от IIS к Kestrel для обработки запроса. Этот метод хостинга получил название «OutOfProcess».

В .NET Core 2.2 была представлена ​​новая модель хостинга под названием «InProcess». Вместо того чтобы IIS пересылал запросы в Kestrel, он обслуживает запросы внутри IIS. Это намного быстрее при обработке запросов, потому что не нужно пересылать запрос в Kestrel. Однако это была необязательная функция, и не использовалась по умолчанию.

В .NET Core 3.1 внутрипроцессная модель размещения уже настроена по умолчанию, что значительно повышает пропускную способность запросов ASP.NET Core в IIS. При тестировании мы фиксировали двукратное увеличение производительности системы при большом количестве запросов.

Хотя справедливости ради стоит отметить, что при запуске приложения на Linux все равно будет использоваться модель внепроцессного размещения веб-сервера.
И еще, если вы размещаете на своем сервере несколько приложений с внутрипроцессной моделью, вы должны позаботиться о том, чтобы каждое такое приложение имело свой собственный пул.

Маршрутизация Endpoint Routing

В .NET Core 2.1 маршрутизация выполнялась в Middleware (промежуточном программном обеспечении ASP.NET Core MVC) в конце конвейера обработки HTTP-запросов. Это означает, что информация о маршруте, например, какое действие контроллера будет выполнено, была недоступна промежуточному ПО, которое обработало запрос до промежуточного ПО MVC в конвейере запросов. Поэтому начиная с .NET Core 2.2 была введена новая система маршрутизации, основанная на конечных точках (Endpoints), призванная решить вышеупомянутые проблемы.
Теперь в .NET Core 3.1 система маршрутизации Endpoint Routing построена иначе, этап маршрутизации отделен от вызова конечной точки. По сути мы имеем два промежуточных middleware:

  • EndpointRoutingMiddleware — тут определяется, какая конечная точка будет вызвана для каждого пути URL запроса, по сути выполняя роль маршрутизации
  • EndpointMiddleware — вызывает конечную точку

Приложение определяет конечную точку, которая будет отправлена на раннем этапе, в конвейере промежуточного программного обеспечения, чтобы следующее middleware могло использовать эту информацию для предоставления функций, недоступных в текущей конфигурации конвейера.

С# 8.0 синтаксический сахар

Кроме обновления самого .NET Core так же была выпущена и новая версия C# 8.0. Обновлений очень много. Одни из них достаточно глобальны, другие затрагивают косметические улучшения, давая разработчикам так называемый “синтаксический сахар”.

Forever alone

What if you want to distribute an application and don’t want to ask the user to install .NET Core on their machine? (Asking that is sort of rude, right?) Again, .NET Core has the answer: the standalone application.

Creating a standalone application means you can distribute the application to any system and it will run, without the need to have .NET Core installed. This means a faster and easier installation. It also means you can have multiple applications running different versions of .NET Core on the same system. It also seems like it would be useful for, say, running a microservice inside a Linux container. Hmmm…

How to install .NET Core on Linux

The list of Linux distributions on which you can run .NET Core includes Red Hat Enterprise Linux (RHEL), Ubuntu, Debian, Fedora, CentOS, Oracle, and SUSE.

Each distribution has its own installation instructions. For example, consider Fedora 26:

Step 1: Add the dotnet product feed.

        sudo rpm --import https://packages.microsoft.comkeysmicrosoft.asc
        sudo sh -c 'echo -e "\nname=packages-microsoft-com-prod \nbaseurl=https://packages.microsoft.com/yumrepos/microsoft-rhel7.3-prod\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/dotnetdev.repo'

Step 2: Install the .NET Core SDK.

        sudo dnf update
        sudo dnf install libunwind libicu compat-openssl10
        sudo dnf install dotnet-sdk-2.0.0

Понимание версий SDK

Надеюсь, теперь вы всё понимаете про версии среды исполнения .NET Core. Но у нас всё еще остается открытым вопрос про версии SDK/CLI.

Если вы перейдете в папку (на маках нужно смотреть в папку ), вы увидите, какие версии SDK установлены на вашем компьютере. Как видите, у меня установлено две версии: и .

Грубо говоря, SDK — это штука, которая предоставляет команды, связанные со сборкой: , , и т.п.

В общем случае, любая версия SDK, которая больше версии, использованной при создании проекта, может быть использована для его сборки ( и ). Таким образом, вы можете просто использовать SDK версии 2.0 для работы с проектами, созданными в SDK версии 1.0.

Это значит, что в большинстве случаев вы можете использовать для всех проектов последнюю версию SDK. Другая версия SDK может понадобиться, например, если вы хотите собрать проект, использующий файл (в этом случае вам будет нужен RC2 SDK).

Текущая версия SDK также влияет на новые проекты, создаваемые командой . Если вы используете SDK версии 2.0 Preview 1, вы получите приложение на основе , если вы используете SDK версии 1.0, вы получите приложение на основе !

Следующий вопрос — как указать приложению, какую версию SDK нужно использовать.

Сторонние DI контейнеры

То, что мы рассматривали и то, что фактически реализует ASP.NET Core DI контейнер по умолчанию, — constructor injection. Имеется еще возможность внедрить зависимость в property с помощью так называемого property injection, но эта возможность отсутствует у встроенного в ASP.NET Core контейнера. Например, у нас может быть какой-то класс, который вы внедряем как зависимость, и у этого класса есть какое-то public property. Теперь представьте себе, что во время или после того как мы внедряем зависимость, нам нужно задать значение property. Вернемся к примеру похожему на пример, который мы недавно рассматривали.
Если у нас есть такой вот класс:

который мы можем внедрить как зависимость,

то используя стандартный контейнер задать значение для свойства мы не можем.
Если вы захотите использовать такую возможность задать значение для свойства OperationId, то вы можете использовать какой-то сторонний DI контейнер, поддерживающий property injection. К слову сказать property injection не особо рекомендуется использовать. Однако, существуют еще Method Injection и Setter Method Injection, которые вполне могут вам пригодится и которые также не поддерживаются стандартным контейнером.

У сторонних контейнеров могут быть и другие очень полезные возможности. Например, с помощью стороннего контейнера можно внедрять зависимость только в контролеры, у которых в названии присутствует определенное слово. И довольно часто используемый кейс – DI контейнеры, оптимизированные на быстродействие.
Вот список некоторых сторонних DI контейнеров, поддерживаемых ASP.NET Core: Autofac, Castle Windsor, LightInject, DryIoC, StructureMap, Unity

Хоть при использовании стандартного DI контейнера и нельзя использовать property/method injection, но зато можно внедрить зависимый сервис в качестве параметра конструктора реализовав паттерн «Фабрика» следующим образом:

В данном случае GetService вернет null если зависимый сервис не найден. Есть вариация GetRequiredService, которая выбросит исключение в случае, если зависимый сервис не найден.
Процесс получения зависимого сервиса с помощью GetService фактически применяет паттерн Service locator.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector