Продолжаем делиться материалом по работе с ASP.NET Core. В прошлой статье мы рассказывали о развертывании приложения ASP.NET Core на Nano Server со службами IIS. Сегодня поговорим о создании внешнего интерфейса веб-службы для вашего приложения.
По умолчанию службы Azure Service Fabric не предоставляют общедоступный интерфейс для веб-служб. Для того чтобы сделать приложение функциональным для HTTP-клиентов, необходимо создать веб-проект, который будет работать в качестве точки входа и обмениваться данными с отдельными службами.
В этом материале мы добавим в приложение Visual Studio веб-службу для службы счетчиков с отслеживанием состояния. Если вы не знакомы с базовым процессом создания приложений в Visual Studio, вам сюда.
Добавление службы ASP.NET Core к приложению
ASP.NET Core — это простое кросс-платформенное средство для веб-разработки, с помощью которого можно создавать современные пользовательские веб-интерфейсы и веб-API. Давайте добавим проект веб-API ASP.NET в существующее приложение:
1. Открыв проект приложения в обозревателе решений, нажмите правую кнопку мыши на Services и выберите пункт Add > New Service Fabric Service.
2. На странице Create a Service выберите ASP.NET Core и укажите имя для данной службы.
3. На следующей странице представлен набор шаблонов проекта ASP.NET Core. Обратите внимание, что это те же шаблоны, которые используются при создании проекта ASP.NET Core вне приложения Service Fabric. В данном руководстве мы будем использовать Web API. Однако вы можете использовать эти методы и для создания полноценного веб-приложения.
Примечание: для дальнейшей работы, необходимо установить .NET Core 1.0.
После создания веб-API в приложении будет две службы. По мере доработки приложения можно тем же способом добавлять новые службы. Каждая из этих служб может быть обновлена отдельно, в том числе и до определенной версии.
Примечание: подробная информация о создании служб ASP.NET Core приведена в документации по ASP.NET Core.
Запуск приложения
Чтобы лучше представить предпринятые нами шаги, давайте развернем новое приложение и рассмотрим поведение по умолчанию, связанное с использованием шаблона веб-API ASP.NET Core:
1. Для отладки приложения нажмите клавишу F5 в Visual Studio.
2. После завершения развертывания при помощи Visual Studio запустится браузер с корневым каталогом службы веб-API ASP.NET, например localhost:33003. Номер порта присваивается произвольно и может отличаться. Шаблон веб-API не предоставляет поведение по умолчанию для корневого каталога, в результате чего в браузере отобразится сообщение об ошибке.
3. Добавьте к адресу в браузере путь /api/values
. Тем самым будет вызван метод Get
объекта ValuesController в шаблоне веб-API. Он вернет ответ по умолчанию, предоставленный шаблоном, — массив JSON, содержащий две строки:
После выполнения действий, приведенных в данном руководстве, значения по умолчанию будут заменены последним значением счетчика службы с отслеживанием состояния.
Подключение служб
Service Fabric предоставляет свободу во взаимодействии со службами Reliable Services. В одном приложении могут быть как службы, доступные по TCP, так и службы, доступные по HTTP REST API, а также службы, доступные через веб-сокеты (о возможных вариантах и подборе идеального соотношения можно прочитать в статье). Здесь мы будем применять один из самых простых подходов и используем классы ServiceProxy/ServiceRemotingListener
, предоставляемые в пакете SDK.
В подходе с использованием ServiceProxy
(основанном на удаленных вызовах процедур или RPC) определяется интерфейс, выступающий в качестве общедоступного контракта службы. Затем этот интерфейс применяется для создания класса прокси для взаимодействия со службой.
Создание интерфейса
Начнем с создания интерфейса, который будет выполнять роль контракта между службой с отслеживанием состояния и ее клиентами, включая проект ASP.NET Core:
1. В обозревателе решений нажмите на решении правую кнопку мыши и выберите пункт Add > New Project.
2. На левой панели навигации выберите Visual C#, затем выберите шаблон Class Library. Убедитесь, что выбрана версия .NET Framework 4.5.2.
3. Чтобы интерфейс мог использоваться ServiceProxy
, он должен быть производным от интерфейса IService. Этот интерфейс включен в один из пакетов NuGet Service Fabric. Чтобы добавить пакет, нажмите правую кнопку мыши на проекте библиотеки классов и выберите Manage NuGet Packages.
4. Найдите пакет Microsoft.ServiceFabric.Services и установите его.
5. В библиотеке классов создайте интерфейс при помощи одиночного интерфейса GetCountAsync
и выполните расширение интерфейса из IService.
namespace MyStatefulService.Interfaces
{
using Microsoft.ServiceFabric.Services.Remoting;
public interface ICounter: IService
{
Task<long> GetCountAsync();
}
}
Реализация интерфейса в службе с отслеживанием состояния
Теперь, когда интерфейс определен, необходимо реализовать его в службе с отслеживанием состояния:
1. В службе с отслеживанием состояния добавьте ссылку на проект библиотеки классов, который содержит данный интерфейс.
2. Найдите класс, который наследуется от StatefulService
, например MyStatefulService
, и выполните его расширение для реализации интерфейса ICounter
.
using MyStatefulService.Interfaces;
...
public class MyStatefulService : StatefulService, ICounter
{
// ...
}
3. Теперь реализуйте одиночный метод, указанный в интерфейсе ICounter
, — GetCountAsync
.
public async Task<long> GetCountAsync()
{
var myDictionary =
await this.StateManager.GetOrAddAsync<IReliableDictionary<string, long>>("myDictionary");
using (var tx = this.StateManager.CreateTransaction())
{
var result = await myDictionary.TryGetValueAsync(tx, "Counter");
return result.HasValue ? result.Value : 0;
}
}
Предоставление службы с отслеживанием состояния при помощи прослушивателя удаленного взаимодействия в службе
После реализации интерфейса ICounter
последним этапом по обеспечению возможности вызова службы с отслеживанием состояния из других служб будет открытие коммуникационного канала. Для служб с отслеживанием состояния Service Fabric предоставляет переопределяемый метод под названием CreateServiceReplicaListeners
. При помощи этого метода можно указать один или несколько прослушивателей связи на основании типа коммуникации, который требуется использовать в службе.
Примечание: эквивалентом метода для открытия коммуникационного канала для службы без отслеживания состояния является CreateServiceInstanceListeners
.
В нашем примере мы заменим существующий метод CreateServiceReplicaListeners
и воспользуемся экземпляром ServiceRemotingListener
, который создает конечную точку RPC, вызываемую клиентами с помощью ServiceProxy
.
using Microsoft.ServiceFabric.Services.Remoting.Runtime;
...
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new List<ServiceReplicaListener>()
{
new ServiceReplicaListener(
(context) =>
this.CreateServiceRemotingListener(context))
};
}
Использование класса ServiceProxy для взаимодействия со службой
Подготовленная нами служба с отслеживанием состояния готова к получению трафика от других служб. Поэтому остается только добавить код для взаимодействия с ней из веб-службы ASP.NET:
1. В проекте ASP.NET добавьте ссылку на библиотеку классов, которая содержит интерфейс ICounter
.
2. Из меню Build откройте Configuration Manager. Должно отобразиться примерно следующее:
Обратите внимание, что для проекта библиотеки классов MyStatefulService.Interface выбран вариант Any CPU (Любой процессор). Для корректной работы с Service Fabric должна использоваться 64-разрядная платформа. Откройте выпадающее меню Platform (Платформа), выберите New и создайте конфигурацию 64-разрядной платформы:
3. Добавьте в проект ASP.NET пакет Microsoft.ServiceFabric.Services, как вы делали ранее для проекта библиотеки классов. Будет добавлен класс ServiceProxy
.
4. В папке Controllers откройте класс ValuesController
. Обратите внимание, что на данный момент метод Get
возвращает встроенный строковый массив значений value1 и value2, соответствующих тем, которые мы видели ранее в браузере. Замените данную реализацию следующим кодом:
using MyStatefulService.Interfaces;
using Microsoft.ServiceFabric.Services.Remoting.Client;
...
public async Task<IEnumerable<string>> Get()
{
ICounter counter =
ServiceProxy.Create<ICounter>(new Uri("fabric:/MyApplication/MyStatefulService"), new ServicePartitionKey(0));
long count = await counter.GetCountAsync();
return new string[] { count.ToString() };
}
Первая строка кода — ключевая. Для добавления прокси-сервера ICounter в службы с отслеживанием состояния необходимо предоставить два типа данных: идентификатор раздела и имя службы.
Создание разделов может использоваться для масштабирования служб с отслеживанием состояния: вы можете разбивать их состояние на разные сегменты на основании указанного вами ключа, например, ID клиента или почтового индекса. В данном приложении служба с отслеживанием состояния имеет только один раздел, поэтому ключ не имеет значения. Любой указанный ключ будет приводить к одному и тому же разделу. Более подробная информация о создании разделов приведена в статье.
Имя службы — это уникальный код ресурса в формате fabric:/<application_name>/<service_name>.
Имея эти данные, Service Fabric может с точностью идентифицировать компьютер, на который должен быть отправлен запрос. Класс ServiceProxy
также согласованно переключает операции на другой компьютер, если на компьютере, на котором размещен раздел службы с отслеживанием состояния, произошел сбой. Данная абстракция упрощает написание кода клиента для работы с другими службами.
После создания прокси-сервера следует вызвать метод GetCountAsync и получить его результат.
5. Нажмите клавишу F5, чтобы запустить измененное приложение. Как и в прошлый раз, автоматически запустится браузер и загрузится корневой каталог веб-проекта. Добавьте путь «api/values», отобразится текущее возвращаемое значение счетчика:
Обновляйте браузер, чтобы отслеживать изменения показаний счетчика.
Важно помнить, что для веб-сервера ASP.NET Core, указанного в шаблоне и известного как Kestrel, не поддерживается обработка прямого трафика Интернета. Для рабочих сценариев рассмотрите возможность размещения конечных точек ASP.NET Core за службой API Management или другим шлюзом с доступом в Интернет. Обратите внимание, что Service Fabric не поддерживается для развертывания в службах IIS.
Обмен данными с субъектами
Здесь мы описываем добавление веб-интерфейса для обеспечения связи со службой с отслеживанием состояния. Однако сходную модель можно использовать для обмена данными с субъектами. Это даже проще.
При создании проекта субъекта в Visual Studio автоматически создается проект интерфейса. Этот интерфейс можно использовать для создания в веб-проекте прокси-сервера субъекта для взаимодействия с субъектом. Коммуникационный канал предоставляется автоматически. Поэтому вам не нужно предпринимать какие-либо действия по настройке ServiceRemotingListener
, как в случае со службами с отслеживанием состояния.
Как работают веб-службы на локальном кластере
Развернутое на локальном кластере приложение Service Fabric, как правило, можно развернуть в кластере с несколькими компьютерами. Это приложение будет работать должным образом. Это объясняется тем, что локальный кластер представляет собой конфигурацию из пяти узлов, расположенную на одном компьютере.
Однако с веб-службами связана одна ключевая особенность. Если кластер не включен в подсистему балансировки нагрузки, как это предусмотрено в среде Azure, вам нужно убедиться, что веб-службы развернуты на каждом компьютере. Это необходимо, так как балансировщик нагрузки будет просто выполнять циклический перебор трафика между компьютерами. Это можно сделать, указав для параметра InstanceCount
службы специальное значение «−1».
При выполнении веб-службы локально, наоборот, необходимо убедиться, что запущен только один экземпляр службы. В противном случае возникнут конфликты с несколькими процессами, которые прослушивают тот же путь и порт. Поэтому для локальных развертываний счетчику экземпляров веб-службы нужно присвоить значение «1».
Более подробную информация о настройке разных значений для разных сред можно найти в статье.
Первая статья из серии ASP.NET Core: ASP.NET Core на Nano Server.
Автор: Microsoft