服务器配置
接收器是通过 UseOrleans(IHostBuilder, Action<HostBuilderContext,ISiloBuilder>) 扩展方法和多个补充选项类以编程方式配置的。 Orleans 中的选项类遵循 .NET 中的选项模式,可以通过文件、环境变量和任何有效的配置提供程序加载。
silo 配置有几个关键方面:
- 群集提供程序
- (可选)Orleans 群集信息
- (可选)用于接收器到接收器和客户端到接收器通信的终结点
下面是定义群集信息、使用 Azure 群集并配置应用程序部分的 silo 配置示例:
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 silo 的成员资格,包括检测节点故障和自动重新配置。
为了可靠地管理群集成员资格,Orleans 将使用 Azure 表、SQL Server 或 Apache ZooKeeper 来同步节点。
在此示例中,使用 Azure 表作为成员资格提供程序。
Orleans 群集信息
若要选择性地配置群集,请使用 ClusterOptions
作为 ISiloBuilder
实例上 Configure 方法的类型参数。
siloBuilder.Configure<ClusterOptions>(options =>
{
options.ClusterId = "my-first-cluster";
options.ServiceId = "SampleApp";
})
可在此指定两个选项:
- 将
ClusterId
设置为"my-first-cluster"
:这是 Orleans 群集的唯一 ID。 使用此 ID 的所有客户端和 silo 能够直接相互通信。 不过,你可以选择为不同的部署使用不同的ClusterId
。 - 将
ServiceId
设置为"SampleApp"
:这是应用程序的唯一 ID,该 ID 将由某些提供程序(例如持久性提供程序)使用。 此 ID 应保持稳定,而不能在不同的部署中有变化。
默认情况下,Orleans 将对 ServiceId
和 ClusterId
使用 "default"
值。 在大多数情况下,无需更改这些值。 二者中 ServiceId
更重要,它用于区分不同的逻辑服务,以便这些服务可以共享后端存储系统但不会相互干扰。 ClusterId
用于确定哪些主机将相互连接并形成群集。
在每个群集中,所有主机都必须使用相同的 ServiceId
。 但多个群集可以共享一个 ServiceId
。 这可以实现蓝/绿部署方案,即在关闭其他部署(群集)之前启动另一个新部署(群集)。 这种情况常见于 Azure 应用服务中托管的系统。
更常见的情况是,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 silo 有两种典型的终结点配置:
- 接收器到接收器终结点用于同一群集中接收器之间的通信。
- 客户端到接收器(或网关)终结点用于同一群集中客户端和接收器之间的通信。
在大多数情况下,使用此方法就足够了,但你可以根据需要进一步对它进行自定义。 下面是如何将外部 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);
})
在内部,silo 将侦听 0.0.0.0:40000
和 0.0.0.0:50000
,但在成员资格提供程序中发布的值将是 172.16.0.42:11111
和 172.16.0.42:30000
。
silo 是通过 SiloHostBuilder 和多个补充选项类以编程方式配置的。 Orleans 中的选项类遵循 .NET 中的选项模式,可以通过文件、环境变量和任何有效的配置提供程序加载。
silo 配置有几个关键方面:
- Orleans 群集信息
- 群集提供程序
- 用于 silo 到 silo 和客户端到 silo 通信的终结点
- 应用程序部件
下面是定义群集信息、使用 Azure 群集并配置应用程序部分的 silo 配置示例:
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 silo 的成员资格,包括检测节点故障和自动重新配置。
为了可靠地管理群集成员资格,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 的所有客户端和 silo 能够直接相互通信。 不过,你可以选择为不同的部署使用不同的ClusterId
。 - 将
ServiceId
设置为"AspNetSampleApp"
:这是应用程序的唯一 ID,该 ID 将由某些提供程序(例如持久性提供程序)使用。 此 ID 应保持稳定,而不能在不同的部署中有变化。
默认情况下,Orleans 将对 ServiceId
和 ClusterId
使用 "default"
值。 在大多数情况下,无需更改这些值。 二者中 ServiceId
更重要,它用于区分不同的逻辑服务,以便这些服务可以共享后端存储系统但不会相互干扰。 ClusterId
用于确定哪些主机将相互连接并形成群集。
在每个群集中,所有主机都必须使用相同的 ServiceId
。 但多个群集可以共享一个 ServiceId
。 这可以实现蓝/绿部署方案,即在关闭其他部署(群集)之前启动另一个新部署(群集)。 这种情况常见于 Azure 应用服务中托管的系统。
更常见的情况是,ServiceId
和 ClusterId
在应用程序的生存期内保持固定,并会用到滚动部署策略。 这种情况常见于在 Kubernetes 和 Service Fabric 中托管的系统。
终结点
siloBuilder.ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
Orleans silo 有两种典型的终结点配置:
- silo 到 silo 终结点,用于同一群集中 silo 之间的通信
- 客户端到 silo 终结点(或网关),用于同一群集中客户端和 silo 之间的通信
在此示例中,我们使用了帮助器方法 .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
,它将用于 silo 到 silo 通信的端口设置为 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);
})
在内部,silo 将侦听 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 加载用户程序集和类型。 这些程序集称为应用程序部件。 所有 Grain、Grain 接口和序列化程序都是使用应用程序部件发现的。
应用程序部件是使用 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
)添加到每个包含 Grain、Grain 接口或序列化程序的项目是确保这些属性存在的建议方法。 生成时代码生成仅支持 C#。 对于 F#、Visual Basic 和其他 .NET 语言,可以在配置期间通过上述 WithCodeGeneration 方法生成代码。 有关代码生成的详细信息,请参阅相应的部分。