当前位置: 首页 > 工具软件 > grain > 使用案例 >

Orleans 2.0 官方文档 —— 4.3 Grains -> grain的标识

明利
2023-12-01

grain的标识

在面向对象的环境中,对象的标识很难与对它的引用区分开来。因此,当使用new创建对象时,返回的引用,表示其标识的所有方面——除了那些将对象映射到它所表示的某个外部实体的方面。

在分布式系统中,对象引用不能表示实例标识,因为引用通常仅限于单个地址空间。对于.NET引用来说,情况当然如此。此外,一个grain必须有一个标识,不管它是否被激活,这样我们可以根据需要激活它。因此,grain有一个主键。主键可以是全局唯一标识符(GUID),长整数或字符串。

主键的作用域是grain类型。因此,grain的完整标识是由grain的类型及其主键组成的。

grain的调用者决定应该使用哪种方案。可选项有:

  • long
  • GUID
  • string
  • GUID + string
  • long + string

因为底层的数据是相同的,所以这些方案可以互换使用。当使用长整数时,实际上会创建一个GUID并用零填充。

需要单个grain实例(例如字典或注册表)的情况,可以使用Guid.Empty作为其键来获得益处。这仅仅是一个约定,但通过遵循约定,调用方就能很清楚在做什么,正如我们在第一个教程中所看到的那样。

使用GUID

当有多个进程可以请求grain时,GUID很有用,例如Web Farm中的多个Web服务器。您不需要协调键的分配,这可能会导致系统中引入单点故障,或者系统端对可能出现瓶颈的资源的锁定。GUID碰撞的可能性非常小,因此在构建Orleans系统时,它们也许是默认的选择。

在client代码中通过GUID引用grain:

var grain = grainFactory.GetGrain<IExample>(Guid.NewGuid());

在grain代码中取回主键:

public override Task OnActivateAsync()
{
    Guid primaryKey = this.GetPrimaryKey();
    return base.OnActivateAsync();
}

使用Long

也可以使用长整数,如果将grain持久化到关系数据库中,那么这是有意义的在关系数据库中,数字索引比GUID更受欢迎。

在client代码中引用长整数的grain:

var grain = grainFactory.GetGrain<IExample>(1);

在grain的代码中取回主键:

public override Task OnActivateAsync()
{
    long primaryKey = this.GetPrimaryKeyLong();
    return base.OnActivateAsync();
}

使用String

也可以使用string。

在client代码中通过string来引用grain:

var grain = grainFactory.GetGrain<IExample>("myGrainKey");

在grain的代码中取回主键:

public override Task OnActivateAsync()
{
    string primaryKey = this.GetPrimaryKeyString();
    return base.OnActivateAsync();
}

使用复合主键

如果您的系统不适合GUID或long,您可以选择复合主键,它允许您使用GUID或long和字符串的组合来引用grain。

您可以将您的接口继承自'IGrainWithGuidCompoundKey'或'IGrainWithIntegerCompoundKey',如下所示:

public interface IExampleGrain : Orleans.IGrainWithIntegerCompoundKey
{
    Task Hello();
}

在client代码中,这会在grain工厂的方法GetGrain中,添加第二个参数。

var grain = grainFactory.GetGrain<IExample>(0, "a string!", null);

要访问grain中的复合键,我们可以在GetPrimaryKey方法上调用重载:

public class ExampleGrain : Orleans.Grain, IExampleGrain
{
    public Task Hello()
    {
        string keyExtension;
        long primaryKey = this.GetPrimaryKeyLong(out keyExtension);
        Console.WriteLine("Hello from " + keyExtension);
        Task.CompletedTask;
    }
}
  •  
 类似资料: