news 2026/9/25 5:48:43

Orleans 9.x 升级至 10.x 迁移实战指南:包版本、行为变更、序列化状态兼容与并行集群部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Orleans 9.x 升级至 10.x 迁移实战指南:包版本、行为变更、序列化状态兼容与并行集群部署
  • 后端
  • 微服务

【免费下载链接】orleans

Cloud Native application framework for .NET

项目地址:https://gitcode.com/gh_mirrors/or/orleans
点击查看免费下载

本篇技术指南聚焦于将基于 .NET 的云原生框架 Orleans 的应用从 9.x 系列升级到 10.x 系列,完整覆盖包版本集中管理、UnorderedAttribute与OrleansConstructorAttribute等源码级弃用处理、CancelRequestOnTimeout超时取消行为变更、SQL Server ADO.NET 客户端切换、序列化与持久化状态兼容性验证,以及并行集群部署与回滚演练。读完本文,你将获得一套可执行、可验证、可回滚的 Orleans 主版本升级方案。

升级起点与目标假设

在执行迁移前,先确认以下前提,避免在升级过程中混入无关变量:

  • 应用运行在最新的 Orleans 9.x 补丁版本上,优先推荐Orleans 9.2.1。
  • 应用及其依赖支持.NET 8 或 .NET 10。
  • 解决方案中所有 Orleans 包将统一移动到同一个当前的 Orleans 10.x 补丁版本。
  • 已部署的 Orleans 9.x 版本所对应的 Provider 架构(数据库表结构等)保持当前状态。

需要特别说明的是:Orleans 10 的包同时面向 .NET 8 与 .NET 10 编译。将应用重新定向到 .NET 10 可以作为一个独立的变更步骤;在首次迁移部署中继续保持 .NET 8,可以显著减少 Orleans 升级过程中的变量数量,降低排障难度。

变更总览

领域Orleans 10 影响需要采取的动作
源码与分析器UnorderedAttribute与OrleansConstructorAttribute已标记为过时(obsolete)移除UnorderedAttribute;仅在确实需要 DI 构造函数选择时替换OrleansConstructorAttribute
行为MessagingOptions.CancelRequestOnTimeout默认值改为false如果应用依赖超时后自动发送取消,必须显式设置该选项
ADO.NET 提供程序SQL Server 默认改用Microsoft.Data.SqlClient及其 invariant 名称移除System.Data.SqlClient,更新 invariant,并逐一测试每个 ADO.NET 提供程序
序列化与状态Orleans 10 不要求从 Orleans 9 重写线格式(wire-format)或 grain 状态保留序列化器 ID、别名、Provider 序列化器设置以及存储类型的兼容性
托管泛型宿主(generic host)的UseOrleans*与UseOrleansClient*模型保持现状已在 Orleans 9 使用这些 API 的应用无需重写托管代码
放置策略Orleans 9.2 已把默认放置策略改为ResourceOptimizedPlacement保持该默认值;若需要确定性连续性,则在升级前显式注册RandomPlacement
取消Orleans 10 为观察者(observers)和系统目标(system targets)新增取消支持每个 grain 方法最多保留一个CancellationToken参数,并测试超时/取消竞态
定时器Orleans 10 没有新的定时器破坏性变更继续使用RegisterGrainTimer*;Grain.RegisterTimer*早在 Orleans 8.2 就已过时
调用过滤器Orleans 10 没有新的过滤器注册模型继续在ISiloBuilder或IClientBuilder上注册入站/出站过滤器
部署跨主版本的混合集群不受文档化兼容性保证覆盖除非你的混合版本拓扑已经过专门验证,否则请使用并行 Orleans 10 集群

集中管理包版本

主版本升级中最常见的故障源之一是包版本漂移——不同项目引用了不同的 Orleans 补丁版本。推荐使用 NuGetCentral Package Management(CPM)集中对齐所有包版本:

<Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <OrleansVersion>10.2.2</OrleansVersion> </PropertyGroup> <ItemGroup> <PackageVersion Include="Microsoft.Orleans.Client" Version="$(OrleansVersion)" /> <PackageVersion Include="Microsoft.Orleans.Sdk" Version="$(OrleansVersion)" /> <PackageVersion Include="Microsoft.Orleans.Server" Version="$(OrleansVersion)" /> </ItemGroup> </Project>

执行迁移时应使用当前最新的稳定版 Orleans 10.x 补丁。解决方案中用到的每个 Provider 包(如聚类、持久化、提醒、流式处理的存储提供程序)都要以相同的 Orleans 版本加入同一份中央版本管理文件中,确保Microsoft.Orleans.*全家桶版本完全对齐。

处理源码级警告:两个弃用特性

Orleans 10 将两个特性标记为过时,代码编译时会出现警告,需要逐一处理。升级的第一步是消除这些警告。

移除UnorderedAttribute

UnorderedAttribute在 Orleans 10 中不产生任何效果。仓库源码 GrainAttributeConcurrency.cs 中对它的定义和注释给出了明确依据:

[AttributeUsage(AttributeTargets.Interface)] [Obsolete("Message ordering is not guaranteed regardless of whether this attribute is used. This attribute has no effect.")] public sealed class UnorderedAttribute : Attribute { }

源码注释明确指出:Orleans 本来就不保证基于该属性进行消息排序,因此无论是否使用该属性,消息顺序都没有保证。请把它从 grain 接口上移除,不要试图寻找替代语义。

仅在依赖注入场景替换OrleansConstructorAttribute

OrleansConstructorAttribute在 Orleans 10 中不再被 Orleans 识别。看 Annotations.cs 中的定义即可确认:

[AttributeUsage(AttributeTargets.Constructor)] [Obsolete("Use GeneratedActivatorConstructorAttribute instead. This attribute is not recognized by Orleans.")] public sealed class OrleansConstructorAttribute : ActivatorUtilitiesConstructorAttribute { }

替换规则如下:

  • 如果可序列化类型需要通过依赖注入来选择构造函数,改用GeneratedActivatorConstructorAttribute或ActivatorUtilitiesConstructorAttribute。GeneratedActivatorConstructorAttribute(见 Annotations.cs)指示生成的 activator 实现使用该构造函数进行实例化,可用于调用需要注入依赖的构造函数。
  • 需要强调的是:这两个替代属性都不会为反序列化数据成员选择构造函数。反序列化走的是序列化器自身的激活路径,与 DI 构造函数选择是两条独立的机制。

另外,不要在本次清理中改动成员 ID(IdAttribute值)或构造函数可见的状态——这属于下一节要讲的序列化兼容性红线。

显式配置超时取消:CancelRequestOnTimeout

Orleans 10 将MessagingOptions.CancelRequestOnTimeout的默认值改为false。这一行为变更意味着:调用方超时后会停止等待响应,但Orleans 不会自动向目标发送取消信号。如果应用依赖“超时即取消对端执行”的旧行为,必须显式开启。

仓库源码 MessagingOptions.cs 中对该选项的注释与默认值给出了实现层证据:

/// <summary> /// Whether request cancellation should be attempted when a request times out. /// </summary> /// <remarks> /// Request cancellation may involve sending a cancellation message to the silo which hosts the target grain. /// Defaults to <see langword="false"/>. /// </remarks> public bool CancelRequestOnTimeout { get; set; }

该选项在运行时确实会触发向承载目标 grain 的 silo 发送取消消息:在 SharedCallbackData.cs 与 CallbackData.cs 中,超时回调逻辑会依据CancelRequestOnTimeout决定是否发起请求取消。

需要在发起调用的客户端(Client)和 silo(Silo)两侧同时设置。迁移示例片段位于 Orleans10MigrationExamples.cs:

public static void ConfigureTimeoutCancellation(ISiloBuilder siloBuilder) { siloBuilder.Configure<SiloMessagingOptions>(options => { options.CancelRequestOnTimeout = true; }); } public static void ConfigureTimeoutCancellation(IClientBuilder clientBuilder) { clientBuilder.Configure<ClientMessagingOptions>(options => { options.CancelRequestOnTimeout = true; }); }

注意:无论该选项如何设置,超时都不代表目标一定停止了执行。超时与对端完成是两个独立事件,grain 方法必须保持可安全重试(幂等或可补偿)的设计。

更新 SQL Server ADO.NET 配置

Orleans 10 的 ADO.NET 聚类(clustering)、持久化(persistence)、提醒(reminders)和流式处理(streaming)在 SQL Server 上默认改用Microsoft.Data.SqlClient。仓库中 AdoNetInvariants.cs 定义的 SQL Server invariant 名称即为:

public const string InvariantNameSqlServer = "Microsoft.Data.SqlClient";

按以下步骤完成切换:

  1. 移除对System.Data.SqlClient的直接包引用。
  2. 通过你的中央包策略引入Microsoft.Data.SqlClient。请使用应用所支持的最新版本,不要照抄早期迁移指南中老旧的固定版本号。
  3. 将 Provider invariant 从System.Data.SqlClient改为Microsoft.Data.SqlClient。
  4. 按需应用从当前已部署 schema 版本到目标 Orleans 版本之间所需的 Provider 迁移脚本。
  5. 对聚类、grain 存储、提醒、流式处理进行独立测试,逐个验证,不要一次合并验证掩盖单点故障。

迁移脚本按数据库类型存放于仓库的迁移目录中,按版本顺序依次应用:

  • 聚类迁移脚本(如SQLServer-Clustering-3.7.0.sql、PostgreSQL-Clustering-3.6.0.sql、MySQL-Clustering-3.7.0.sql、Oracle-Clustering-3.7.0.sql)
  • 持久化迁移脚本(如PostgreSQL-Persistence-3.6.0.sql)
  • 提醒迁移脚本(如PostgreSQL-Reminders-3.6.0.sql)

需要澄清的关键点:客户端库切换本身不会改变 grain 状态的负载格式(payload format)。但它会改变连接默认值与认证行为,因此必须在 staging 环境验证连接加密、证书、认证、重试策略与事务行为——这些变化可能来自Microsoft.Data.SqlClient与System.Data.SqlClient之间的默认配置差异,而非 Orleans 自身。

保持序列化与状态兼容

从 Orleans 9 到 Orleans 10,没有任何一个迁移步骤要求重编号IdAttribute值或重写持久化状态。升级的核心策略是“保住既有契约”:

  • 不要重用或重编号IdAttribute值。IdAttribute是序列化成员的唯一标识(见 Annotations.cs),任何成员 ID 变化都会破坏新旧版本的读取兼容。
  • 当类型或程序集移动时,保持AliasAttribute值稳定。类型别名用于在类型跨程序集移动时保持序列化身份稳定(见 Annotations.cs)。
  • 不要调整 record 主构造函数参数的顺序——它被用作隐式序列化器 ID(GenerateSerializerAttribute默认对 record 类型自动包含主构造函数参数,见 Annotations.cs)。
  • 在运行时升级期间,保持已配置的 grain 存储序列化器不变。
  • 用 Orleans 10 读取代表性旧状态、写入,再验证回滚构建版本仍能读取这些数据,然后才允许生产写入。

一个稳定的可序列化状态示例(片段见 Orleans10MigrationExamples.cs):

[GenerateSerializer] public sealed class CounterState { [Id(0)] public int Value { get; set; } }
  • 按顺序应用 ADO.NET schema 脚本,并且在应用任何不可逆脚本之前,先验证回滚兼容性。

关于版本容忍规则(version-tolerance)的完整说明,参见 Orleans 序列化配置指南。

确认托管、放置策略、定时器与调用过滤器

这部分用于逐项确认 Orleans 10 中“不需要改动”的既有能力,避免过度修改引入风险。

托管模型:无需重写

如果 Orleans 9 应用已经使用Host.CreateApplicationBuilder、UseOrleans*或UseOrleansClient*,则不需要任何托管代码重写。泛型宿主模型在 Orleans 10 中保持当前形态。

放置策略:默认已是ResourceOptimizedPlacement

Orleans 9.2 已将默认放置策略改为ResourceOptimizedPlacement。仓库源码 DefaultSiloServices.cs 中可以看到该策略被注册为默认单例:

services.TryAddSingleton<PlacementStrategy, ResourceOptimizedPlacement>();

其放置决策实现位于 ResourceOptimizedPlacementDirector.cs。如果你的生产集群仍然依赖RandomPlacement,请在升级前显式声明该策略,而不是隐式依赖旧默认值:

public static void KeepRandomPlacement(ISiloBuilder siloBuilder) { siloBuilder.Services.AddSingleton<PlacementStrategy, RandomPlacement>(); }

定时器:继续使用RegisterGrainTimer

Orleans 10 没有新的定时器破坏性变更,请继续使用GrainBaseExtensions.RegisterGrainTimer*;旧的Grain.RegisterTimer*API 早在 Orleans 8.2 就已过时。在从旧 API 迁移到新 API 以保持旧行为时,注意GrainTimerCreationOptions.Interleave需要设置为true——新 API 的回调默认是**非交错(non-interleaving)**的。参考示例:

public override Task OnActivateAsync(CancellationToken cancellationToken) { _timer = this.RegisterGrainTimer( callback: DoWorkAsync, options: new GrainTimerCreationOptions { DueTime = TimeSpan.FromSeconds(1), Period = TimeSpan.FromSeconds(10), Interleave = true }); return Task.CompletedTask; } private static Task DoWorkAsync(CancellationToken cancellationToken) => Task.CompletedTask;

(完整片段见 Orleans10MigrationExamples.cs。)

调用过滤器:在 Orleans 构建器上注册

调用过滤器必须注册在Orleans 构建器上,而不是直接注册到IServiceCollection。入站过滤器用委托注册、出站过滤器用类型注册:

public static void ConfigureCallFilters(ISiloBuilder siloBuilder) { siloBuilder.AddIncomingGrainCallFilter(async context => { await context.Invoke(); }); siloBuilder.AddOutgoingGrainCallFilter<MyOutgoingCallFilter>(); }
public sealed class MyOutgoingCallFilter : IOutgoingGrainCallFilter { public Task Invoke(IOutgoingGrainCallContext context) => context.Invoke(); }

(完整片段见 Orleans10MigrationExamples.cs。)

取消支持:每个方法最多一个CancellationToken

Orleans 10 为观察者和系统目标新增了取消支持。grain 接口方法中每个方法最多保留一个CancellationToken参数,并务必测试超时与取消之间的竞态:

public interface ICancelableWorkGrain : IGrainWithStringKey { Task RunAsync(CancellationToken cancellationToken); }

(片段见 Orleans10MigrationExamples.cs。)

部署并保留回滚能力

完整的部署与回滚流程详见仓库文档 Upgrade deployment and rollback(升级部署与回滚)。该文档明确了一个关键边界:Orleans 文档化的运行时兼容保证仅覆盖同一主版本家族内的 patch 与 minor 版本;跨主版本的滚动升级默认视为不受支持,除非针对确切的运行时版本、Provider、应用契约与流量模式通过了你自己的资格验证(qualification suite)。

因此,默认采用独立的 Orleans 10 并行(blue-green)集群,并保留 Orleans 9 集群及其最后兼容的状态恢复点,直到满足以下全部条件:

  • Orleans 10 的客户端与 silo 已通过冒烟测试与负载测试。
  • Provider 写入的数据已被证明回滚构建版本可读(双向读取验证)。
  • 队列或流中不存在 Orleans 9 无法识别的类型形状的负载。
  • 指标显示激活放置、调用延迟、取消、提醒与存储行为均稳定。

并行集群部署的推荐顺序(详见 deployment-and-rollback.md):

  1. 使用与旧状态读取验证相同版本的应用契约修订构建目标版本。
  2. 创建与生产集群独立的成员关系与网关发现的并行集群。
  3. 指向克隆的 Provider 数据或 staging 数据集,验证聚类、存储、提醒、流、定时器、过滤器、取消与放置。
  4. 生产环境以无写入流量起步并完成冒烟测试。
  5. 逐步迁移一小部分可观测的流量。
  6. 仅当延迟、失败、激活、存储、提醒、流与取消指标稳定后,再增加流量。
  7. 在任何可能产生并发激活或冲突写入的共享状态切换前,先停止旧集群的写入。
  8. 在回滚窗口过期前,保留旧部署与恢复点。

两个独立集群不应同时运行在同一 grain 存储或提醒表上,除非 Provider 与应用已为该拓扑做过专门设计。

升级检查清单

  • 升级到最新的 Orleans 9.x 补丁并消除构建警告。
  • 将所有Microsoft.Orleans.*包对齐到同一个当前 10.x 补丁。
  • 首次部署保持 .NET 8,或将 .NET 10 重定向单独认证。
  • 移除UnorderedAttribute,替换有效的OrleansConstructorAttribute用法。
  • 显式设置CancelRequestOnTimeout。
  • 如使用 SQL Server,替换System.Data.SqlClient及其 invariant。
  • 保留序列化器 ID、别名与 grain 存储序列化器设置。
  • 确认放置策略、定时器交错与调用过滤器注册方式。
  • 验证 Provider 架构与代表性持久化状态。
  • 准备并演练并行集群部署与回滚。

延伸阅读

  • 升级部署与回滚(并行集群序列、回滚前置条件与步骤)
  • Orleans 序列化配置指南(版本容忍规则)
  • 迁移代码示例片段:Orleans10MigrationExamples.cs
  • ADO.NET 迁移脚本:聚类 · 持久化 · 提醒
  • 后端
  • 微服务

【免费下载链接】orleans

Cloud Native application framework for .NET

项目地址:https://gitcode.com/gh_mirrors/or/orleans
点击查看免费下载

相关推荐

上一篇:5分钟快速上手Microverse:从零开始构建你的AI虚拟世界
下一篇:LangChain量化交易完全指南:构建智能算法交易系统的终极教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 5:45:00

电磁辐射防护工程手册:距离、时间、材质三维度实操指南

简介&#xff1a;本资源是一份面向公众健康科普与工程防护实践的电磁辐射知识手册&#xff0c;适用于电子电气从业者、环境安全管理人员、高校相关专业师生及关注日常辐射防护的普通读者。内容系统梳理电磁辐射的多源性&#xff08;自然、医疗、家电、通信等&#xff09;、三类…

作者头像 李华
网站建设 2026/9/25 5:44:55

智能工厂四层架构落地指南:技术、系统、数据、应用架构拆解

简介&#xff1a;这份PPT资料聚焦智能工厂的顶层设计&#xff0c;面向制造业信息化规划人员、数字化转型负责人及智能制造方向的学习者&#xff0c;帮助系统理解从业务调研到落地实施的完整架构方法论。内容围绕总体设计方法、业务调研与分析、智能工厂总体规划、建设路线规划及…

作者头像 李华
网站建设 2026/9/25 5:41:44

SUMO交通仿真入门:从零搭建交叉口仿真与TraCI控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华