90%代码由AI生成,31万行复杂业务系统如何重构?美团技术团队分享实战经验
2026/5/8 18:54:29
internalIRemoteGrainDirectoryGetDirectoryReference(SiloAddresssilo){returnthis.grainFactory.GetSystemTarget<IRemoteGrainDirectory>(Constants.DirectoryServiceType,silo);}这个方法的核心作用是:
IRemoteGrainDirectory接口远程代理publicTGrainInterfaceGetSystemTarget<TGrainInterface>(GrainTypegrainType,SiloAddressdestination)whereTGrainInterface:ISystemTarget{vargrainId=SystemTargetGrainId.Create(grainType,destination);returnthis.GetSystemTarget<TGrainInterface>(grainId.GrainId);}SystemTargetGrainId.Create创建一个特殊的GrainIdGrainId包含了目标服务类型和目标 Silo 地址// 在 GrainDirectoryPartition.cs 中的调用示例internalstaticSystemTargetGrainIdCreateGrainId(SiloAddresssiloAddress,intpartitionIndex)=>SystemTargetGrainId.Create(Constants.GrainDirectoryPartitionType,siloAddress,partitionIndex.ToString(CultureInfo.InvariantCulture));SystemTargetGrainId是一种特殊的 GrainIdpublicTGrainInterfaceGetSystemTarget<TGrainInterface>(GrainIdgrainId)whereTGrainInterface:ISystemTarget{ISystemTargetreference;ValueTuple<GrainId,Type>key=ValueTuple.Create(grainId,typeof(TGrainInterface));lock(this.typedSystemTargetReferenceCache){if(this.typedSystemTargetReferenceCache.TryGetValue(key,outreference)){return(TGrainInterface)reference;}reference=this.GetGrain<TGrainInterface>(grainId);this.typedSystemTargetReferenceCache[key]=reference;return(TGrainInterface)reference;}}this.GetGrain<TGrainInterface>(grainId)创建新代理publicTGrainInterfaceGetGrain<TGrainInterface>(GrainIdgrainId)whereTGrainInterface:IAddressable{return(TGrainInterface)this.CreateGrainReference(typeof(TGrainInterface),grainId);}publicIAddressableGetGrain(GrainIdgrainId,GrainInterfaceTypeinterfaceType){returnthis.referenceActivator.CreateReference(grainId,interfaceType);}referenceActivator是GrainReferenceActivator的实例// 在 SystemTarget.cs 中的使用示例publicGrainReferenceGrainReference=>_selfReference??=_shared.GrainReferenceActivator.CreateReference(_id.GrainId,default);GrainId和GrainInterfaceType创建一个代理对象TGrainInterface接口(在这里是IRemoteGrainDirectory)创建的远程代理是一个动态生成的类,它:
IRemoteGrainDirectory接口RegisterAsync、UnregisterAsync等)当调用代理的方法时(如remoteProxy.RegisterAsync(grainAddress)):
GrainId中的 Silo 地址Orleans 的消息传递系统负责:
lock(this.typedSystemTargetReferenceCache){if(this.typedSystemTargetReferenceCache.TryGetValue(key,outreference)){return(TGrainInterface)reference;}// ... 创建新代理并缓存}SystemTarget 与普通 Grain 的区别:
publicTGrainInterfaceGetSystemTarget<TGrainInterface>(GrainTypegrainType,SiloAddressdestination)whereTGrainInterface:ISystemTarget假设我们有两个 Silo:Silo1 和 Silo2
// 在 Silo1 中执行 SiloAddress silo2Address = SiloAddress.FromParsableString("192.168.1.100:11111"); IRemoteGrainDirectory remoteProxy = GetDirectoryReference(silo2Address); // 这个调用会被自动转换为网络消息发送到 Silo2 await remoteProxy.RegisterAsync(grainAddress, null, 1);RemoteGrainDirectory实例RegisterAsync方法GetDirectoryReference(silo) └─→ GrainFactory.GetSystemTarget<IRemoteGrainDirectory>(grainType, silo) ├─→ SystemTargetGrainId.Create(grainType, silo) // 创建包含目标地址的 GrainId └─→ GetSystemTarget<IRemoteGrainDirectory>(grainId) ├─→ 检查缓存 (typedSystemTargetReferenceCache) │ └─→ 缓存命中 → 返回现有代理 └─→ 缓存未命中 → 创建新代理 ├─→ GetGrain<IRemoteGrainDirectory>(grainId) │ └─→ CreateGrainReference(typeof(IRemoteGrainDirectory), grainId) └─→ referenceActivator.CreateReference(grainId, interfaceType) └─→ 创建包含消息发送逻辑的代理对象 └─→ 缓存新代理 └─→ 返回代理对象GetDirectoryReference 方法创建远程代理的机制是 Orleans 分布式通信的核心:
这种设计使得开发人员可以专注于业务逻辑,而无需关心底层的网络通信细节,体现了 Orleans 的核心设计理念:让分布式编程变得简单。