使用 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 表、SQL Server 或 Apache ZooKeeper 同步节点。
在此示例中,我们使用 Azure 表作为成员资格提供程序。
Orleans 聚类信息
若要可选地配置聚类,请使用ClusterOptions
作为Configure实例上ISiloBuilder
方法的类型参数。
siloBuilder.Configure<ClusterOptions>(options =>
{
options.ClusterId = "my-first-cluster";
options.ServiceId = "SampleApp";
})
在此处,请指定两个选项:
- 将
ClusterId
设置为"my-first-cluster"
:这是 Orleans 群集的唯一 ID。 使用此 ID 的所有客户端和孤岛都可以直接相互通信。 不过,您可以选择为不同的部署使用不同的ClusterId
。 - 将
ServiceId
设置为"SampleApp"
:这是某些提供者(如持久性提供者)所用的应用程序唯一 ID。 此 ID 应保持稳定,且不会在部署之间更改。
默认情况下,Orleans 使用 "default"
来处理ServiceId
和ClusterId
。 在大多数情况下,这些值不需要更改。
ServiceId
更重要的是,可以区分不同的逻辑服务,从而允许它们共享后端存储系统,而不会造成干扰。
ClusterId
确定哪些主机连接到群集。
在每个群集中,所有主机都必须使用相同的 ServiceId
。 但是,多个群集可以共享一个 ServiceId
。 这将支持蓝/绿部署场景,可在关闭另一个部署之前启动新的部署(集群)。 对于 Azure 应用服务中托管的系统,这是典型的。
常见的情况是,ServiceId
和 ClusterId
在应用程序的生命周期内保持固定,并且您使用滚动部署策略。 这适用于 Kubernetes 和 Service Fabric 中托管的系统。
端点
默认情况下,Orleans 监听用于 silo 到 silo 的通信的端口 11111
的所有接口,以及用于客户端到 silo 的通信的端口 30000
。 若要替代此行为,请调用 ConfigureEndpoints(ISiloBuilder, Int32, Int32, AddressFamily, Boolean) 并传入要使用的端口号。
siloBuilder.ConfigureEndpoints(siloPort: 17_256, gatewayPort: 34_512)
在前面的代码中:
- 筒仓端口设置为
17_256
。 - 网关端口设置为
34_512
.
Orleans 仓筒有两种典型的终结点配置类型:
- 粒仓到粒仓端点:用于同一群集中的粒仓之间的通信。
- 客户端到存储(或网关)终结点:用于同一群集中的客户端与存储之间的通信。
在大多数情况下,此方法应足够,但如果需要,可以进一步自定义此方法。 下面是将外部 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 表、SQL Server 或 Apache ZooKeeper 同步节点。
在此示例中,我们使用 Azure 表作为成员资格提供程序。
Orleans 聚类信息
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "my-first-cluster";
options.ServiceId = "AspNetSampleApp";
})
在这里,我们做了两件事:
- 将
ClusterId
设置为"my-first-cluster"
:这是 Orleans 群集的唯一 ID。 使用此 ID 的所有客户端和孤岛都可以直接相互通信。 不过,您可以选择为不同的部署使用不同的ClusterId
。 - 将
ServiceId
设置为"AspNetSampleApp"
:这是某些提供者(如持久性提供者)所用的应用程序唯一 ID。 此 ID 应保持稳定,且不会在部署之间更改。
默认情况下,Orleans 使用 "default"
来处理ServiceId
和ClusterId
。 在大多数情况下,这些值不需要更改。
ServiceId
更重要的是,可以区分不同的逻辑服务,从而允许它们共享后端存储系统,而不会造成干扰。
ClusterId
确定哪些主机连接到群集。
在每个群集中,所有主机都必须使用相同的 ServiceId
。 但是,多个群集可以共享一个 ServiceId
。 这将支持蓝/绿部署场景,可在关闭另一个部署之前启动新的部署(集群)。 对于 Azure 应用服务中托管的系统,这是典型的。
常见的情况是,ServiceId
和 ClusterId
在应用程序的生命周期内保持固定,并且您使用滚动部署策略。 这适用于 Kubernetes 和 Service Fabric 中托管的系统。
端点
siloBuilder.ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
Orleans 仓筒有两种典型的终结点配置类型:
- 粒仓到粒仓端点:用于同一群集中的粒仓之间的通信。
- 客户端到接收器终结点(或网关):用于同一群集中的客户端和接收器之间的通信。
在示例中,我们使用辅助方法 .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
,该方法将孤立系统之间通信端口设定为 11111
,并将网关端口设定为 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 加载用户程序集和类型。 这些程序集称为应用程序部件。 Orleans 使用应用程序部件发现所有粒度、粒度接口和序列化程序。
通过在IApplicationPartManager和ConfigureApplicationParts
上使用IClientBuilder扩展方法来配置应用程序部件,这些应用程序部件可通过ISiloHostBuilder访问。 该方法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 语言,可以通过上述提到的方法在配置时间生成代码。 在 相应的部分中查找有关代码生成的详细信息。