简单聊一下什么是Grain
我们知道Orleans给C#程序提供了分布式的便捷能力,而Grain可以说是一种业务形态的表示,比如我们声明PlayerGrain,GameGrain等,Orleans会给Grain创建代理,然后我们使用它的时候,就跟调用里面的方法那样,无需关心它最终会跑到哪个线程,哪台物理机上,这些Orleans已经给我们封装好了,而且同一个Grain是线程安全的。
Grain组成
Grain由标识,用户行为,状态组成。这些名词不用太刻意去记,简单的说就是PlayerGrain里面有个叫PlayerId的标识, 然后PlayerGrain里面玩家可以移动,跑,放技能的行为,然后这个PlayerGrain是一个轻量级引用,太久没访问了,状态就变成死亡被回收了。
举例
我们以游戏中最常见的战队举例, 我们就暂且命名UnionGrain吧,暂且说一下游戏中战队业务,战队属于公共业务,同一个战队玩家访问同一个战队进程和线程,因为是公共,且访问量压力较大的业务,所以需要做到分布式负载均衡去抗压。
条件
我们假设有两台服务器A,B都是战队服务器组成集群。
设计Grain
标识: UnionId 行为: 加入战队,退出战队... 后面自己扩展!
public interface IUnionGrain : IGrainWithGuidKey
{
/// <summary>
/// 加入战队
/// </summary>
/// <param name="playerId">玩家Id</param>
/// <returns></returns>
public Task JoinUnion(long playerId);
/// <summary>
/// 离开战队
/// </summary>
/// <param name="playerId">玩家Id</param>
/// <returns></returns>
public Task LeaveUnion(long playerId);
}
public class UnionGrain : Grain, IUnionGrain
{
public Task JoinUnion(long playerId)
{
return Task.CompletedTask;
}
public Task LeaveUnion(long playerId)
{
return Task.CompletedTask;
}
}
以上就简单的声明了一个Grain,是不是感觉好简单,是的就是好简单,Grain是一个代理对象,我们可以像调用对象方法一样简单去调用,比如这个是通过某个UnionId创建出来的Grain,我调用了JoinUnion方法时,他会通过Union去Hash都A或者B服务器,然后把请求打到这个UnionId下的Grain进行处理,做到同一个战队下线程安全。关于IGrainWithGuidKey后续了解吧,其实就是标识的接口...