Service Fabric을 사용한 호스트
Orleans(은)는 Microsoft.ServiceFabric.Services 및 Microsoft를 사용하여 Azure Service Fabric을 호스팅 할 수 있습니다.Orleans.서버 NuGet 패키지. Orleans(은)는 노이즈 자체 분포를 관리하므로 사일로는 분할되지 않은 상태 비저장 서비스로 호스트되어야 합니다. 분할 및 상태 저장과 같은 다른 호스팅 옵션은 더 복잡하며 개발자에 의한 추가 사용자 지정 없이는 이점을 얻을 수 없습니다. 분할되지 않고 상태 비국적 Orleans에 호스트하는 것이 좋습니다.
사일로로서의 Service Fabric 상태 비저장 서비스
새 Service Fabric 애플리케이션을 만들거나 기존 애플리케이션에 Orleans(을)를 추가하는 경우 프로젝트의 Microsoft.ServiceFabric.Services
및 Microsoft.Orleans.Server
패키지 참조가 모두 필요합니다. 상태 비저장 서비스 프로젝트에는 ICommunicationListener 구현과 StatelessService의 하위 클래스가 필요합니다.
사일로 수명 주기는 일반적인 통신 수신기 수명 주기를 따릅니다.
- ICommunicationListener.OpenAsync를 사용하여 초기화됩니다.
- ICommunicationListener.CloseAsync를 사용하면 정상적으로 종료됩니다.
- 또는 ICommunicationListener.Abort를 사용하면 갑자기 종료됩니다.
Orleans 사일로는 IHost 범위 내에서 살 수 있기 때문에 ICommunicationListener
구현은 IHost
에 둘러싸인 래핑입니다. IHost
는 OpenAsync
메서드에서 초기화되고 CloseAsync
메서드에서 정상적으로 종료됩니다.
ICommunicationListener |
IHost 상호 작용 |
---|---|
OpenAsync | IHost 인스턴스가 만들어지고 StartAsync 호출이 수행됩니다. |
CloseAsync | 호스트 인스턴스에서 StopAsync 호출이 대기됩니다. |
Abort | StopAsync 호출은 GetAwaiter().GetResult() 를 사용하여 강제로 평가됩니다. |
클러스터 지원
공식 클러스터링 지원은 다음을 비롯한 다양한 패키지에서 사용할 수 있습니다.
- Microsoft.Orleans. Clustering.AzureStorage
- Microsoft.Orleans.Clustering.AdoNet
- Microsoft.Orleans.Clustering.DynamoDB
CosmosDB, Kubernetes, Redis 및 Aerospike와 같은 다른 서비스에 사용할 수 있는 여러 타사 패키지도 있습니다. 자세한 내용은 Orleans에서 클러스터 관리를 참조하세요.
예제 프로젝트
상태 비정상 서비스 프로젝트에서 다음 예제와 같이 ICommunicationListener
인터페이스를 구현합니다.
using Microsoft.Extensions.Hosting;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
namespace ServiceFabric.HostingExample;
internal sealed class HostedServiceCommunicationListener : ICommunicationListener
{
private IHost? _host;
private readonly Func<Task<IHost>> _createHost;
public HostedServiceCommunicationListener(Func<Task<IHost>> createHost) =>
_createHost = createHost ?? throw new ArgumentNullException(nameof(createHost));
/// <inheritdoc />
public async Task<string?> OpenAsync(CancellationToken cancellationToken)
{
try
{
_host = await _createHost.Invoke();
await _host.StartAsync(cancellationToken);
}
catch
{
Abort();
throw;
}
// This service does not expose any endpoints to Service Fabric for discovery by others.
return null;
}
/// <inheritdoc />
public async Task CloseAsync(CancellationToken cancellationToken)
{
if (_host is { } host)
{
await host.StopAsync(cancellationToken);
}
_host = null;
}
/// <inheritdoc />
public void Abort()
{
IHost? host = _host;
if (host is null)
{
return;
}
using CancellationTokenSource cancellation = new();
cancellation.Cancel(false);
try
{
host.StopAsync(cancellation.Token).GetAwaiter().GetResult();
}
catch
{
// Ignore.
}
finally
{
_host = null;
}
}
}
HostedServiceCommunicationListener
클래스는 Func<Task<IHost>> createHost
생성자 매개 변수를 허용합니다. 이 매개 변수는 나중에 OpenAsync
메서드에서 IHost
인스턴스를 만드는 데 사용됩니다.
상태 비지정 서비스 프로젝트의 다음 부분은 StatelessService
클래스를 구현하는 것입니다. 다음 예제에서는 StatelessService
클래스의 하위 클래스를 보여줍니다.
using System.Fabric;
using Microsoft.Extensions.Hosting;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
namespace ServiceFabric.HostingExample;
public sealed class OrleansHostedStatelessService : StatelessService
{
private readonly Func<StatelessServiceContext, Task<IHost>> _createHost;
public OrleansHostedStatelessService(
Func<StatelessServiceContext, Task<IHost>> createHost, StatelessServiceContext serviceContext)
: base(serviceContext) =>
_createHost = createHost ?? throw new ArgumentNullException(nameof(createHost));
/// <inheritdoc/>
protected sealed override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
// Create a listener which creates and runs an IHost
yield return new ServiceInstanceListener(
context => new HostedServiceCommunicationListener(() => _createHost(context)),
nameof(HostedServiceCommunicationListener));
}
}
앞의 예제에서 OrleansHostedStatelessService
클래스는 ICommunicationListener
인스턴스 생성을 담당합니다. CreateServiceInstanceListeners
메서드는 서비스가 초기화될 때 Service Fabric 런타임에서 호출합니다.
다음 예제에서는 이러한 두 클래스를 함께 풀링하여 완전한 상태 비저장 서비스 프로젝트 Program.cs 파일을 보여 줍니다.
using System.Fabric;
using Microsoft.Extensions.Hosting;
using Microsoft.ServiceFabric.Services.Runtime;
using ServiceFabric.HostingExample;
try
{
// The ServiceManifest.XML file defines one or more service type names.
// Registering a service maps a service type name to a .NET type.
// When Service Fabric creates an instance of this service type,
// an instance of the class is created in this host process.
await ServiceRuntime.RegisterServiceAsync(
"Orleans.ServiceFabric.Stateless",
context => new OrleansHostedStatelessService(
CreateHostAsync, context));
ServiceEventSource.Current.ServiceTypeRegistered(
Environment.ProcessId,
typeof(OrleansHostedStatelessService).Name);
// Prevents this host process from terminating so services keep running.
await Task.Delay(Timeout.Infinite);
}
catch (Exception ex)
{
ServiceEventSource.Current.ServiceHostInitializationFailed(
ex.ToString());
throw;
}
static async Task<IHost> CreateHostAsync(StatelessServiceContext context)
{
await Task.CompletedTask;
return Host.CreateDefaultBuilder()
.UseOrleans((_, builder) =>
{
// TODO, Use real storage, something like table storage
// or SQL Server for clustering.
builder.UseLocalhostClustering();
// Service Fabric manages port allocations, so update the
// configuration using those ports. Gather configuration from
// Service Fabric.
var activation = context.CodePackageActivationContext;
var endpoints = activation.GetEndpoints();
// These endpoint names correspond to TCP endpoints
// specified in ServiceManifest.xml
var siloEndpoint = endpoints["OrleansSiloEndpoint"];
var gatewayEndpoint = endpoints["OrleansProxyEndpoint"];
var hostname = context.NodeContext.IPAddressOrFQDN;
builder.ConfigureEndpoints(hostname,
siloEndpoint.Port, gatewayEndpoint.Port);
})
.Build();
}
위의 코드에서
- ServiceRuntime.RegisterServiceAsync 메서드는
OrleansHostedStatelessService
클래스를 Service Fabric 런타임에 등록합니다. CreateHostAsync
대리자는IHost
인스턴스를 만드는 데 사용됩니다.
.NET