サーバー構成
サイロは、UseOrleans(IHostBuilder, Action<HostBuilderContext,ISiloBuilder>) の拡張メソッドといくつかの補助オプション クラスを使用してプログラムによって構成されます。 Orleans のオプション クラスは、「.NET でのオプション パターン」に従い、ファイル、環境変数、および任意の有効な構成プロバイダーを介して読み込むことができます。
サイロ構成にはいくつかの重要な側面があります。
- クラスタリング プロバイダー
- (省略可能) Orleans クラスタリング情報
- (省略可能) サイロ間通信とクライアントとサイロ間通信に使用するエンドポイント
クラスター情報を定義し、Azure クラスタリングを使用し、アプリケーション パーツを構成するサイロ構成の例を以下に示します。
using IHost host = Host.CreateDefaultBuilder(args)
.UseOrleans(builder =>
{
builder.UseAzureStorageClustering(
options => options.ConfigureTableServiceClient(connectionString));
})
.UseConsoleLifetime()
.Build();
ヒント
Orleans 用に開発する場合は、UseLocalhostClustering(ISiloBuilder, Int32, Int32, IPEndPoint, String, String) を呼び出してローカル クラスターを構成できます。 運用環境では、デプロイに適したクラスタリング プロバイダーを使用する必要があります。
クラスタリング プロバイダー
siloBuilder.UseAzureStorageClustering(
options => options.ConfigureTableServiceClient(connectionString))
通常、Orleans 上に構築されたサービスは、専用のハードウェア上またはクラウド内のノードのクラスターにデプロイされます。 開発と基本的なテストのために、Orleans は単一ノード構成でデプロイできます。 ノードのクラスターにデプロイすると、Orleans では、ノード障害の検出や自動再構成など、クラスター内の Orleans サイロのメンバーシップを検出して維持するための一連のプロトコルが内部的に実装されます。
クラスター メンバーシップを確実に管理するために、Orleans ではノードの同期に Azure Table、SQL Server、または Apache ZooKeeper が使用されます。
このサンプルでは、メンバーシップ プロバイダーとしての Azure Table を使用しています。
Orleans クラスタリング情報
必要に応じてクラスタリングを構成するには、ISiloBuilder
インスタンスの Configure メソッドの型パラメーターとして ClusterOptions
を使用します。
siloBuilder.Configure<ClusterOptions>(options =>
{
options.ClusterId = "my-first-cluster";
options.ServiceId = "SampleApp";
})
ここでは、次の 2 つのオプションを指定します。
ClusterId
を"my-first-cluster"
に設定: これは、Orleans クラスターに一意の ID です。 この ID を使用するすべてのクライアントとサイロは、相互に直接通信できます。 しかし、デプロイごとに異なるClusterId
を使用するように選択できます。ServiceId
を"SampleApp"
に設定します。これは、永続化プロバイダーなど、一部のプロバイダーによって使用されるアプリケーションの一意の ID です。 この ID は安定した状態を保ち、デプロイ間で変更されないようにする必要があります。
既定で Orleans では、ServiceId
と ClusterId
の両方に "default"
の値が使用されます。 ほとんどの場合、これらの値を変更する必要はありません。 ServiceId
は 2 つの中でより重要であり、相互に干渉することなくバックエンド ストレージ システムを共有できるように、異なる論理サービスを相互に区別するために使用されます。 ClusterId
は、どのホストが相互に接続し、クラスターを形成するかを決定するために使用されます。
各クラスター内では、すべてのホストで同じ ServiceId
を使用する必要があります。 しかし、複数のクラスターで ServiceId
を共有できます。 これにより、別のデプロイがシャットダウンされる前に新しいデプロイ (クラスター) を開始するブルーグリーン デプロイ シナリオが可能になります。 これは、Azure App Service でホストされているシステムに適しています。
より一般的なケースは、ServiceId
と ClusterId
がアプリケーションの有効期間にわたって固定されたままであり、ローリング デプロイ戦略が使用される場合です。 これは、Kubernetes と Service Fabric でホストされているシステムに適しています。
エンドポイント
既定で Orleans では、サイロ間通信のポート 11111
上、およびクライアントとサイロ間通信のポート 30000
上のすべてのインターフェイスがリッスンされます。 この動作をオーバーライドするには、ConfigureEndpoints(ISiloBuilder, Int32, Int32, AddressFamily, Boolean) を呼び出して、使用するポート番号を渡します。
siloBuilder.ConfigureEndpoints(siloPort: 17_256, gatewayPort: 34_512)
上のコードでは以下の操作が行われます。
- サイロ ポートは
17_256
に設定されます。 - ゲートウェイ ポートは
34_512
に設定されます。
Orleans サイロには、次の 2 種類の一般的なエンドポイント構成があります。
- サイロ間エンドポイントは、同じクラスター内のサイロ間の通信に使用されます。
- クライアントとサイロ (またはゲートウェイ) 間のエンドポイントは、同じクラスター内のクライアントとサイロ間の通信に使用されます。
ほとんどの場合、このメソッドで十分なはずですが、必要に応じてさらにカスタマイズできます。 ポート転送で外部 IP アドレスを使用する方法の例を以下に示します。
siloBuilder.Configure<EndpointOptions>(options =>
{
// Port to use for silo-to-silo
options.SiloPort = 11_111;
// Port to use for the gateway
options.GatewayPort = 30_000;
// IP Address to advertise in the cluster
options.AdvertisedIPAddress = IPAddress.Parse("172.16.0.42");
// The socket used for client-to-silo will bind to this endpoint
options.GatewayListeningEndpoint = new IPEndPoint(IPAddress.Any, 40_000);
// The socket used by the gateway will bind to this endpoint
options.SiloListeningEndpoint = new IPEndPoint(IPAddress.Any, 50_000);
})
内部的には、サイロで 0.0.0.0:40000
と 0.0.0.0:50000
をリッスンしますが、メンバーシップ プロバイダーで公開される値は 172.16.0.42:11111
と 172.16.0.42:30000
です。
サイロは、SiloHostBuilder といくつかの補助オプション クラスを使用してプログラムによって構成されます。 Orleans のオプション クラスは、「.NET でのオプション パターン」に従い、ファイル、環境変数、および任意の有効な構成プロバイダーを介して読み込むことができます。
サイロ構成にはいくつかの重要な側面があります。
- Orleans クラスタリング情報
- クラスタリング プロバイダー
- サイロ間およびクライアントとサイロ間通信に使用するエンドポイント
- アプリケーション パーツ
クラスター情報を定義し、Azure クラスタリングを使用し、アプリケーション パーツを構成するサイロ構成の例を以下に示します。
var silo = Host.CreateDefaultBuilder(args)
.UseOrleans(builder =>
{
builder
.UseAzureStorageClustering(
options => options.ConnectionString = connectionString)
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "my-first-cluster";
options.ServiceId = "AspNetSampleApp";
})
.ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
.ConfigureApplicationParts(
parts => parts.AddApplicationPart(typeof(ValueGrain).Assembly).WithReferences())
})
.UseConsoleLifetime()
.Build();
このサンプルで使用する手順を詳しく見ていきましょう。
クラスタリング プロバイダー
siloBuilder.UseAzureStorageClustering(
options => options.ConnectionString = connectionString)
通常、Orleans 上に構築されたサービスは、専用のハードウェア上またはクラウド内のノードのクラスターにデプロイされます。 開発と基本的なテストのために、Orleans は単一ノード構成でデプロイできます。 ノードのクラスターにデプロイすると、Orleans では、ノード障害の検出や自動再構成など、クラスター内の Orleans サイロのメンバーシップを検出して維持するための一連のプロトコルが内部的に実装されます。
クラスター メンバーシップを確実に管理するために、Orleans ではノードの同期に Azure Table、SQL Server、または Apache ZooKeeper が使用されます。
このサンプルでは、メンバーシップ プロバイダーとして Azure Table を使用しています。
Orleans クラスタリング情報
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "my-first-cluster";
options.ServiceId = "AspNetSampleApp";
})
ここでは、次の 2 つのことを行います。
ClusterId
を"my-first-cluster"
に設定: これは、Orleans クラスターに一意の ID です。 この ID を使用するすべてのクライアントとサイロは、相互に直接通信できます。 しかし、デプロイごとに異なるClusterId
を使用するように選択できます。ServiceId
を"AspNetSampleApp"
に設定します。これは、永続化プロバイダーなど、一部のプロバイダーによって使用されるアプリケーションの一意の ID です。 この ID は安定した状態を保ち、デプロイ間で変更されないようにする必要があります。
既定で Orleans では、ServiceId
と ClusterId
の両方に "default"
の値が使用されます。 ほとんどの場合、これらの値を変更する必要はありません。 ServiceId
は 2 つの中でより重要であり、相互に干渉することなくバックエンド ストレージ システムを共有できるように、異なる論理サービスを相互に区別するために使用されます。 ClusterId
は、どのホストが相互に接続し、クラスターを形成するかを決定するために使用されます。
各クラスター内では、すべてのホストで同じ ServiceId
を使用する必要があります。 しかし、複数のクラスターで ServiceId
を共有できます。 これにより、別のデプロイがシャットダウンされる前に新しいデプロイ (クラスター) を開始するブルーグリーン デプロイ シナリオが可能になります。 これは、Azure App Service でホストされているシステムに適しています。
より一般的なケースは、ServiceId
と ClusterId
がアプリケーションの有効期間にわたって固定されたままであり、ローリング デプロイ戦略が使用される場合です。 これは、Kubernetes と Service Fabric でホストされているシステムに適しています。
エンドポイント
siloBuilder.ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
Orleans サイロには、次の 2 種類の一般的なエンドポイント構成があります。
- 同じクラスター内のサイロ間の通信に使用されるサイロ間エンドポイント
- 同じクラスター内のクライアントとサイロ間の通信に使用される、クライアントからサイロへのエンドポイント (またはゲートウェイ)
このサンプルでは、サイロ間通信に使用されるポートを 11111
に設定し、ゲートウェイのポートを 30000
に設定するヘルパー メソッド .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
を使用しています。
このメソッドでは、リッスンするインターフェイスを検出します。
ほとんどの場合、このメソッドで十分なはずですが、必要に応じてさらにカスタマイズできます。 ポート転送で外部 IP アドレスを使用する方法の例を以下に示します。
siloBuilder.Configure<EndpointOptions>(options =>
{
// Port to use for silo-to-silo
options.SiloPort = 11111;
// Port to use for the gateway
options.GatewayPort = 30000;
// IP Address to advertise in the cluster
options.AdvertisedIPAddress = IPAddress.Parse("172.16.0.42");
// The socket used for client-to-silo will bind to this endpoint
options.GatewayListeningEndpoint = new IPEndPoint(IPAddress.Any, 40000);
// The socket used by the gateway will bind to this endpoint
options.SiloListeningEndpoint = new IPEndPoint(IPAddress.Any, 50000);
})
内部的には、サイロで 0.0.0.0:40000
と 0.0.0.0:50000
をリッスンしますが、メンバーシップ プロバイダーで公開される値は 172.16.0.42:11111
と 172.16.0.42:30000
です。
アプリケーション パーツ
siloBuilder.ConfigureApplicationParts(
parts => parts.AddApplicationPart(
typeof(ValueGrain).Assembly)
.WithReferences())
この手順は技術的には必要ありません (構成されていない場合、Orleans では現在のフォルダー内のすべてのアセンブリがスキャンされます) が、開発者はこれを構成することをお勧めします。 この手順は、Orleans でユーザー アセンブリと型を読み込むのに役立ちます。 これらのアセンブリは、アプリケーション パーツと呼ばれます。 すべてのグレイン、グレイン インターフェイス、およびシリアライザーは、アプリケーション パーツを使用して検出されます。
アプリケーション パーツは、IApplicationPartManager を使用して構成されます。これには、IClientBuilder および ISiloHostBuilder の ConfigureApplicationParts
拡張メソッドを使用してアクセスできます。 ConfigureApplicationParts
メソッドでは Action<IApplicationPartManager>
デリゲートが受け入れられます。
IApplicationPartManager の次の拡張メソッドでは一般的な用途がサポートされます。
- ApplicationPartManagerExtensions.AddApplicationPart この拡張メソッドを使用して、単一のアセンブリを追加できます。
- ApplicationPartManagerExtensions.AddFromAppDomain では、
AppDomain
に現在読み込まれているすべてのアセンブリを追加します。 - ApplicationPartManagerExtensions.AddFromApplicationBaseDirectory では、現在の基本パス内のすべてのアセンブリを読み込んで追加します (AppDomain.BaseDirectory に関するページを参照)。
上記のメソッドによって追加されたアセンブリは、戻り値の型で次の拡張メソッド (IApplicationPartManagerWithAssemblies) を使用して補足できます。
- ApplicationPartManagerExtensions.WithReferences では、追加されたパーツから参照されているすべてのアセンブリを追加します。 これにより、推移的に参照されるアセンブリが直ちに読み込まれます。 アセンブリの読み込みエラーは無視されます。
- ApplicationPartManagerCodeGenExtensions.WithCodeGeneration では、追加されたパーツのサポート コードを生成し、パーツ マネージャーに追加します。 これを行うには、
Microsoft.Orleans.OrleansCodeGenerator
パッケージをインストールする必要があり、一般にランタイム コード生成と呼ばれることに注意してください。
型検出では、指定されたアプリケーション パーツに特定の属性が含まれている必要があります。 グレイン、グレイン インターフェイス、またはシリアライザーを含む各プロジェクトにビルド時コード生成パッケージ (Microsoft.Orleans.CodeGenerator.MSBuild
または Microsoft.Orleans.OrleansCodeGenerator.Build
) を追加することは、これらの属性が存在することを確かめるための推奨される方法です。 ビルド時のコード生成では、C# のみがサポートされます。 F#、Visual Basic、およびその他の .NET 言語の場合、上記の WithCodeGeneration メソッドを使用して、構成時にコードを生成できます。 コード生成について詳しくは、対応するセクションを参照してください。
.NET