此概述嵌入在 Hello World 示例应用程序中。
Orleans 的主要概念涉及 silo、客户端和一个或多个 grain。 创建 Orleans 应用涉及配置 silo、配置客户端和编写 grain。
配置接收器
通过 ISiloBuilder 编程方式配置孤岛以及多个补充选项类。 可以在 选项类列表中找到所有选项的列表。
public static async Task SiloMain(string[] args)
{
await Host.CreateDefaultBuilder(args)
.UseOrleans(siloBuilder =>
{
siloBuilder.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
})
.Configure<EndpointOptions>(
options => options.AdvertisedIPAddress = IPAddress.Loopback)
.ConfigureLogging(logging => logging.AddConsole());
})
.RunConsoleAsync();
}
前面的代码:
- 创建默认主机生成器。
- 调用 UseOrleans 配置孤立服务器。
- 使用 localhost 群集进行本地开发。
- 配置群集和服务 ID。
- 配置终结点以侦听环回。
- 添加控制台日志记录。
通过 ISiloHostBuilder 编程方式配置孤岛以及多个补充选项类。 可以在 选项类列表中找到所有选项的列表。
static async Task<ISiloHost> StartSilo(string[] args)
{
var siloHostBuilder = new SiloHostBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
})
.Configure<EndpointOptions>(
options => options.AdvertisedIPAddress = IPAddress.Loopback)
.ConfigureApplicationParts(
parts => parts.AddApplicationPart(typeof(HelloGrain).Assembly).WithReferences())
.ConfigureLogging(logging => logging.AddConsole());
var host = siloHostBuilder.Build();
await host.StartAsync();
return host;
}
| 选项 | 用途 |
|---|---|
.UseLocalhostClustering() |
将客户端配置为连接到本地主机上的接收器。 |
| ClusterOptions | ClusterId 是 Orleans 群集的名称;对于孤岛和客户端,它必须相同,以便它们能够通信。 ServiceId 是用于应用程序的 ID,不能在部署之间更改。 |
| EndpointOptions | 告诉孤岛在哪里倾听。 对于此示例,请使用 loopback。 |
| 选项 | 用途 |
|---|---|
ConfigureApplicationParts |
将 grain 类和接口程序集作为应用程序部件添加到 Orleans 应用程序。 这在 7.0+ 中 Orleans 不需要,因为源生成器会自动处理此情况。 |
加载配置后,生成主机,然后异步启动它。
配置客户端
与孤岛类似,通过 IClientBuilder 和类似的选项类集合配置客户端。
public static async Task ClientMain(string[] args)
{
using IHost host = Host.CreateDefaultBuilder(args)
.UseOrleansClient(clientBuilder =>
{
clientBuilder.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
});
})
.ConfigureLogging(logging => logging.AddConsole())
.Build();
await host.StartAsync();
var client = host.Services.GetRequiredService<IClusterClient>();
Console.WriteLine("Client successfully connected to silo host");
await DoClientWork(client);
await host.StopAsync();
}
前面的代码:
- 创建默认主机生成器。
- 调用 UseOrleansClient 以配置客户端。
- 使用本地主机群集连接到本地存储体。
- 配置群集和服务 ID 以匹配数据孤岛。
- 启动主机并从服务提供商检索 IClusterClient。
与孤岛类似,通过 IClientBuilder 和类似的选项类集合配置客户端。
static async Task<IClusterClient> StartClientWithRetries()
{
_attempt = 0;
var client = new ClientBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
})
.ConfigureLogging(logging => logging.AddConsole())
.Build();
await client.Connect(RetryFilter);
Console.WriteLine("Client successfully connected to silo host");
return client;
}
private static async Task<bool> RetryFilter(Exception exception)
{
if (exception.GetType() != typeof(SiloUnavailableException))
{
Console.WriteLine($"Cluster client failed to connect to cluster with unexpected error. Exception: {exception}");
return false;
}
_attempt++;
Console.WriteLine($"Cluster client attempt {_attempt} of 5 failed to connect to cluster. Exception: {exception}");
if (_attempt > 5)
{
return false;
}
await Task.Delay(TimeSpan.FromSeconds(4));
return true;
}
| 选项 | 用途 |
|---|---|
.UseLocalhostClustering() |
与信息孤岛相同 |
| ClusterOptions | 与信息孤岛相同 |
在配置指南的 “客户端配置 ”部分查找有关配置客户端的更深入指南。
写一个粒子
Grain 是 Orleans 编程模型的关键基元。 它们是应用程序的构建基块 Orleans ,充当隔离、分布和持久性的原子单元。 粒度是表示应用程序实体的对象。 就像在经典 Object-Oriented 编程中一样,粒度封装实体的状态并在代码逻辑中编码其行为。 粒度可以保存彼此的引用,并通过调用通过接口公开的方法进行交互。
这是 Hello World 粒度的代码主体:
public class HelloGrain : Orleans.Grain, IHello
{
private readonly ILogger<HelloGrain> _logger;
public HelloGrain(ILogger<HelloGrain> logger) => _logger = logger;
Task<string> IHello.SayHello(string greeting)
{
_logger.LogInformation("SayHello message received: greeting = '{Greeting}'", greeting);
return Task.FromResult($"You said: '{greeting}', I say: Hello!");
}
}
粒度类实现一个或多个粒度接口。 有关详细信息,请参阅 “粒度 ”部分。
public interface IHello : Orleans.IGrainWithIntegerKey
{
Task<string> SayHello(string greeting);
}
部件如何协同工作
此编程模型基于分布式 Object-Oriented 编程的核心概念构建。 先启动 ISiloHost 。 然后,启动 OrleansClient 程序。 方法Main的OrleansClient调用了启动客户端的方法StartClientWithRetries()。 将客户端传递给 DoClientWork() 方法。
static async Task DoClientWork(IClusterClient client)
{
var friend = client.GetGrain<IHello>(0);
var response = await friend.SayHello("Good morning, my friend!");
Console.WriteLine($"\n\n{response}\n\n");
}
此时,OrleansClient创建对IHello Grain的引用,并通过SayHello()接口调用其IHello方法。 此调用会激活接收器中的粒度。
OrleansClient 向激活的粒度发送问候语。 程序将问候语作为对 OrleansClient 的响应,然后在控制台上显示它。
运行示例应用
若要运行示例应用,请参阅自述文件。