ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Orleans 运行时架构深度解析:从客户端调用到 Grain 激活的完整链路

Orleans 运行时架构深度解析:从客户端调用到 Grain 激活的完整链路 后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载Orleans 以位置透明的 Grain 引用grain reference向应用层屏蔽了分布式系统的复杂性但其运行时内部由多个可独立替换、具备故障感知能力的子系统协同完成每一次调用。本文基于仓库文档 runtime-architecture.md结合源码实现剖析请求从客户端代理经消息中心、目录、放置服务、激活、调度器直到 Grain 方法的完整旅程并解释系统目标system target、一致性边界与公开扩展面——读完你将能理解Grain 身份稳定、激活位置临时这一核心不变量是如何被实现的。核心不变量与总体调用链路Orleans 运行时的设计源自虚拟 Actor 研究论文所提出的位置透明抽象Grain 身份identity是稳定的而其激活activation位置是临时的。每次调用都是一次寻址与路由过程运行时用多个职责单一、可独立替换的子系统协作完成。文档给出了如下端到端调用链路图这条链路揭示了 Orleans 的几大设计决策代理生成应用代码调用的是由源码生成器source generator产出的 Grain 代理对象而不是真正的 Grain 实例统一消息层客户端与 Silo 之间、Silo 与 Silo 之间的所有通信最终都收敛为MessageCenter负责的Message传递激活与身份分离目录directory维护 Grain 身份到激活地址的映射放置服务placement决定新激活落在哪个 Silo而目录与放置的最终交汇点是Catalog——它负责创建并持有ActivationData单线程调度每个激活上的请求最终进入WorkItemGroup调度器由它在单线程上下文中串行执行 Grain 方法从而保证单 Grain 内部无数据竞争。Host 组合Host compositionSilo 是如何被组装起来的Silo 是 .NET Generic HostSilo 是一个 .NET Generic Host所有 Orleans 运行时服务都通过 .NET 依赖注入 注册。SiloHostedService负责启动和停止Orleans.Runtime.Silo而Silo本身驱动有序的 Silo 生命周期。从源码看SiloHostedService 是注册在 DI 中的IHostedService它调用Silo.StartAsync而 Silo.cs 在构造时会取出所有ILifecycleParticipantISiloLifecycle参与者并注册到siloLifecycle随后StartAsync通过siloLifecycle.OnStart(cancellationToken)按阶段启动整个运行时包括创建 Grain 服务、启动平台看门狗Watchdog、最终进入Running状态。默认服务注册集运行时各类子系统的默认装配集中在 DefaultSiloServices.cs 的AddDefaultServices方法中。文档将其归纳为以下几组与源码一一对应子系统职责注册的核心服务见 DefaultSiloServices.cs 中对应代码段网络连接、路由、转发、网关与分发MessageCenter、Gateway、ConnectionManager、SiloConnectionListener、GatewayConnectionListener、SocketSchedulers成员管理MembershipTableManager、MembershipAgent、ClusterHealthMonitor、ClusterMembershipService以及MembershipSystemTarget、SiloStatusOracle、ProbeRequestMonitor等激活定位LocalGrainDirectory、GrainLocator、CachedGrainLocator、DhtGrainLocator、GrainDirectoryResolver新激活的放置选择PlacementService及键控的放置主管director包括RandomPlacementDirector、PreferLocalPlacementDirector、StatelessWorkerDirector、ActivationCountPlacementDirector、HashBasedPlacementDirector、ClientObserversPlacementDirector、SiloRoleBasedPlacementDirector、ResourceOptimizedPlacementDirector本地激活归属ActivationDirectory、Catalog、ActivationData由ActivationDataActivatorProvider创建、ActivationCollector、ActivationWorkingSet本地目标调用与响应生成InsideRuntimeClient、GrainFactory、IGrainReferenceRuntime、GrainReferenceActivator负载与过载决策DeploymentLoadPublisher、EnvironmentStatisticsProvider、OverloadDetector几个值得注意的实现细节默认放置策略DefaultSiloServices通过services.TryAddSingletonPlacementStrategy, ResourceOptimizedPlacement()将默认放置策略设为资源优化放置见 DefaultSiloServices.cs这与文档中使用 keyed placement directors的表述一致配置驱动装配ApplyConfiguration方法会读取配置中Orleans节下的Clustering、Reminders、Journaling、BroadcastChannel、Streaming、GrainStorage、GrainDirectory等子节通过IProviderBuilderISiloBuilder反射解析并装配对应 provider——这正是文档所说多个可独立替换子系统的配置入口生命周期参与几乎每个核心服务都通过AddFromExistingILifecycleParticipantISiloLifecycle, Xxx()挂入 Silo 生命周期实现有序启动与优雅关闭。客户端没有目录与放置的瘦运行时与 Silo 不同外部客户端ClusterClient没有激活目录activation catalog也没有放置服务。它启动一个OutsideRuntimeClient通过网关发现gateway discovery找到可用的客户端网关维护网关连接并通过客户端自己的MessageCenter发送请求。这一点可以在 OutsideRuntimeClient.cs 中印证它内部持有ClientMessageCenter、维护ConcurrentDictionaryCorrelationId, CallbackData callbacks用于响应关联并通过ConsumeServices从 DI 容器解析IGrainReferenceRuntime、IGrainFactory、MessageFactory等组件。Silo 内部也内嵌了一个运行时客户端但其InsideRuntimeClient有能力直接分发请求到本地激活与系统目标无需经过网关。这也是文档所说一个 silo 也内嵌运行时客户端但其InsideRuntimeClient可以直接派发到本地激活与系统目标的代码依据——在 DefaultSiloServices.cs 中InsideRuntimeClient同时以IRuntimeClient形式注册并挂入ILifecycleParticipantISiloLifecycle。一次请求穿越运行时的完整旅程文档给出了请求处理的九步流程这里结合源码逐一展开代理与请求对象生成源码生成器为每个 Grain 接口方法生成代理方法proxy method和一个可调用的请求类型invokable request type。生成器实现在 src/Orleans.CodeGenerator 中如ProxyGenerator.cs、InvokableGenerator.cs、SerializableSourceOutputGenerator.cs配合ApplicationPartAttributeGenerator在编译期完成代理装配。代理将 invokable 交给GrainReferenceRuntime代理方法最终调用 GrainReferenceRuntime.cs 的InvokeMethodAsync。该实现的关键点当没有注册 outgoing 调用过滤器时走快速路径——从ResponseCompletionSourcePool获取响应完成源直接RuntimeClient.SendRequest(...)当存在IOutgoingGrainCallFilter时走InvokeMethodWithFiltersAsync构造OutgoingCallInvokerTResult让过滤器有机会检查或替换调用。这正是文档中Outgoing call filters can inspect or replace the invocation的代码落点。创建 Message、登记回调并发送运行时创建Message为其分配相关标识correlation identity与目标 Grain注册响应回调然后通过MessageCenter发送。客户端侧的回调登记体现在OutsideRuntimeClient的callbacks字典与SharedCallbackData包含ResponseTimeout、CancelRequestOnTimeout、WaitForCancellationAcknowledgement等超时语义见 OutsideRuntimeClient.cs。网关转发与直连路由外部客户端必须通过网关gateway发送而 Silo 之间在已知激活地址时可以直接路由到目标 Silo。接收端解析激活地址接收方的MessageCenter解析激活地址。缓存命中可避免一次目录往返round trip地址过期stale则被失效并重新路由。这依赖CachedGrainLocator的缓存与GrainDirectoryResolver的按类型解析机制。无激活则目录与放置服务协同创建当目标 Grain 尚无激活时目录LocalGrainDirectory与PlacementService协商在一个兼容的 Silo 上创建新激活。PlacementService依据PlacementStrategy与对应 director 从候选集中选择目标。Catalog 创建 ActivationDataCatalog创建ActivationData并且激活过程activation先于排队中的应用请求被派发——即 Grain 的构造函数/激活钩子完成之后请求才会开始执行。Catalog自身继承自SystemTarget见 Catalog.cs同时是ILifecycleParticipantISiloLifecycle与整个 Silo 生命周期同步。调度器执行 Grain 方法ActivationData将请求放入激活调度器WorkItemGroup。入站调用过滤器incoming call filters与生成器产出的 invoker 共同执行 Grain 方法。DefaultSiloServices中注册的GrainContextActivator、IConfigureGrainTypeComponents、ActivationDataActivatorProvider见 DefaultSiloServices.cs共同支撑了这一上下文创建与执行管线。响应沿相关标识返回InsideRuntimeClient创建响应或拒绝rejection响应沿原始 correlation identity 回到等待中的回调。超时语义决定了请求是否真正执行过是消息层无法回答的问题见下文一致性边界。文档指出上述各环节的核心实现分别在 GrainReferenceRuntime.cs、OutsideRuntimeClient.cs、MessageCenter.cs、Catalog.cs 与 InsideRuntimeClient.cs 中可作为深入阅读的入口。系统目标System targets不虚拟激活的可寻址运行时组件系统目标是运行时内部的可寻址组件它们使用 Orleans 消息传递与单线程调度但不具备虚拟激活virtual activation。运行时在明确的 Silo 地址上直接构造它们。成员服务membership、持久化流拉取代理persistent stream pulling agents与激活重平衡协议activation balancing protocols都使用系统目标——因为它们需要消息与调度模型但绝不能是位置透明的虚拟 Actor。从源码看SystemTarget.cs 的类注释直接说明了它的定位Base class for various system services, such as grain directory, reminder service, etc.。其构造方式印证了文档描述的区别有具体的 Silo 位置SystemTargetGrainId.Create(grainType, shared.SiloAddress)将 Silo 地址编入 Grain IDActivationAddress GrainAddress.GetAddress(Silo, _id.GrainId, ActivationId)直接固定地址见 SystemTarget.cs由运行时代码创建与注册系统目标通过 DI 注册并参与 Silo 生命周期而非由放置服务激活不经过放置与目录查找它不依赖PlacementService也不在 Grain 目录中做位置透明的查找参与运行时生命周期而非应用 Grain 生命周期例如MembershipSystemTarget、ClusterManifestSystemTarget都以ILifecycleParticipantISiloLifecycle身份注册见 DefaultSiloServices.cs。对比普通 Grain系统目标在四个维度上有着本质差异位置确定、创建主体是运行时、激活方式为显式构造、生命周期归运行时管理。理解这一区分是理解 Orleans 内部服务如成员协议为什么不受虚拟化约束的关键。一致性边界各子系统的局部契约Orleans并不在所有这些子系统之上实现一个全局事务而是为每个边界定义更窄的一致性契约。文档归纳的五条边界是运行时可扩展性的基石成员表把成员更新串行化为单调有序的视图membership updates are serialized into monotonically ordered views即集群成员视图的单调收敛目录协调一个 Grain 身份对应一个激活地址并修复过期的注册stale registrations激活调度器为单个激活串行化同步工作项synchronous work items这是单线程 Grain语义的保证消息层只关联请求—响应无法推断一个超时的请求是否真的执行过——这正是 at-least-once 语义的来源也是为什么恰好一次需要更上层的机制持久化与流各自定义自己的持久性与确认点acknowledgement points例如流适配器决定队列确认语义而非 Grain 调用的恰好一次。对运行时的扩展者而言这些边界具有直接指导意义文档原文表述务必牢记自定义目录改变的是位置一致性而不是成员一致性放置主管选择的是新激活从哪里开始而不是调用如何被调度流适配器定义的是队列确认而不是 Grain 调用的恰好一次语义。换句话说每个扩展点都只在其所属边界内做出承诺。这解释了为什么 Orleans 允许替换目录自定义放置换流后端却不会因此破坏成员协议或调度保证。公开扩展面用受支持的扩展点而非替换内部类型文档明确建议优先使用受支持的扩展点而不是替换内部运行时类型。以下扩展点是官方认可的兼容边界IPlacementDirector与放置过滤器自定义候选 Silo 的筛选逻辑对应Orleans.Runtime.Placement.IPlacementDirectorIGrainDirectory提供命名 Grain 目录对应Orleans.GrainDirectory.IGrainDirectory序列化器 codec、copier、activator 与 converter扩展线上数据wire处理能力流队列适配器、mapper、balancer、cache 与失败处理器扩展持久化流的能力IProviderBuilderT集成配置驱动的 provider见Orleans.Providers.IProviderBuilder的注册方式DefaultSiloServices.ApplyConfiguration正是通过IProviderBuilderISiloBuilder装配配置节中声明的 provider生命周期参与者lifecycle participants编排 provider 的启动与关闭顺序。同时文档给出了一条重要的兼容性准则内部命名与算法不构成兼容性保证。真正的兼容边界是公共 API、分析器警告与有文档定义的线上身份标识wire identities。换句话说应用的持久兼容性契约落在公共类型与消息线格式上而不是运行时内部类的字段布局或算法细节。小结Orleans 运行时架构可以用一句话概括应用代码面对位置透明的 Grain 引用而每一次调用都被拆解为消息寻址、目录解析、放置决策、激活创建与单线程调度的协作流程。这份架构文档的价值在于划清了各子系统的职责边界与一致性契约Silo 由 Generic Host 与 DI 组合而成默认服务集在 DefaultSiloServices.cs 中集中定义请求链路是代理 →GrainReferenceRuntime→ 运行时客户端 →MessageCenter→ 目录/放置 →Catalog/ActivationData→ 调度器 → Grain 方法 → 响应回传系统目标以固定地址、运行时创建、非虚拟激活的方式承载成员、流拉取与激活重平衡等基础设施协议一致性是分而治之的成员、目录、调度、消息、持久化各守边界扩展者必须遵守局部契约扩展应走公开扩展面内部实现细节不构成兼容性承诺。对于需要深入运行时或构建自定义 provider、目录、放置策略的开发者这份文档与上述源码路径共同构成了从宏观流程到微观实现的完整学习地图。赞分享后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载相关推荐Orleans Grain Extensions 完全指南为 Grain 激活附加运行时接口Orleans Grain Extensions 完全指南为 Grain 激活附加运行时接口 导读 本文深入讲解 Orleans 框架中的 Grain ext后端微服务Orleans Grain 定时器Grain Timers完全指南激活级周期性任务调度Orleans Grain 定时器Grain Timers完全指南激活级周期性任务调度 导读 本文基于 Orleans 官方文档 grains/timer后端微服务Containerd核心架构解析从客户端到运行时Containerd核心架构解析从客户端到运行时 containerd 是一个行业标准的容器运行时强调简单性、健壮性和可移植性。它作为 Linux 和 Wi云原生容器运行时上一篇轻量级协作白板终极指南如何快速部署和高效使用下一篇7步搞定Syncthing跨平台文件同步完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表