
后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载导读本文以仓库中 samples/HelloWorld 这个最精简的入门示例为主线逐步拆解一个 Orleans 应用从「定义 Grain 接口」「实现 Grain 类」到「在 Host 中配置本地集群并完成一次远程调用」的完整链路。读完本文你将掌握 Orleans 的最小可运行项目结构、IGrainWithStringKey与Grain基类的核心语义、IGrainFactory.GetGrain的引用获取方式以及通过UseLocalhostClustering()在开发环境快速启动 Silo 的实战方法并了解底层源码如何支撑这些行为。示例概览一个单项目的 Orleans Hello WorldHello, World!是每位程序员入门时的必经仪式而 samples/HelloWorld/README.md 正是 Orleans 官方给出的这个仪式。整个示例只包含一个控制台项目它的完整流程是启动一个基于HostBuilder的 Orleans 应用本地集群模式通过IGrainFactory获取名为friend的HelloGrain引用调用其SayHello方法并把返回值打印到控制台等待用户按键后优雅停机。示例所演示的三个核心知识点如何快速上手 Orleans如何搭建 Host、启动 Silo如何定义并实现 Grain 接口如何获取 Grain 引用并调用 Grain 方法。项目文件组织非常简洁全部源码位于 samples/HelloWorld 目录下核心文件包括文件作用IHelloGrain.cs定义 Grain 接口契约HelloGrain.csGrain 接口的实现业务逻辑Program.cs宿主构建、集群配置与调用入口HelloWorld.csproj项目文件声明依赖与目标框架Directory.Packages.props集中管理 NuGet 包版本run.cmd / run.shWindows / Linux 一键运行脚本第一步定义 Grain 接口IHelloGrain打开 IHelloGrain.cs可以看到整个接口只有短短几行namespace HelloWorld; public interface IHelloGrain : IGrainWithStringKey { ValueTaskstring SayHello(string greeting); }之所以能判定这是一个Grain 接口是因为它继承了IGrainWithStringKey。这是一个标记接口marker interface其含义是当你想获取一个实现了IHelloGrain的 Grain 实例引用时需要用字符串来标识这个实例。IGrainWithStringKey 在源码中的定义在 src/Orleans.Core.Abstractions/Core/IGrain.cs 中可以看到 Orleans 提供了一组用于标注主键类型的标记接口/// summary /// Marker interface for grains /// /summary public interface IGrain : IAddressable { } /// summary /// Marker interface for grains with see crefGuid/ keys. /// /summary public interface IGrainWithGuidKey : IGrain { } /// summary /// Marker interface for grains with see creflong/ keys. /// /summary public interface IGrainWithIntegerKey : IGrain { } /// summary /// Marker interface for grains with see crefstring/ keys. /// /summary public interface IGrainWithStringKey : IGrain { }IGrain本身又是从IAddressable可寻址派生的这从架构上定义了 Orleans 的核心抽象——每个 Grain 实例都是集群中的一个可寻址实体。除字符串键外Orleans 还支持Guid键IGrainWithGuidKey、long键IGrainWithIntegerKey、复合键等具体可参阅同一文件的其余声明。接口方法的返回值Task 还是 ValueTask本示例的接口方法返回ValueTaskstring而 README 中展示的历史版本返回Taskstring。两者在 Orleans 中都完全支持ValueTask在方法同步完成时可以避免不必要的堆分配属于常见的性能优化写法。无论使用哪一种Orleans 都会把对该接口方法的调用序列化后路由到承载该 Grain 激活的 Silo 上执行对调用方而言表现为一个普通的异步方法。第二步实现 Grain 类HelloGrain接着打开 HelloGrain.csnamespace HelloWorld; public sealed class HelloGrain : Grain, IHelloGrain { public ValueTaskstring SayHello(string greeting) ValueTask.FromResult($Hello, {greeting}!); }HelloGrain之所以被识别为 Grain 实现是因为它继承了Grain基类。在 src/Orleans.Core.Abstractions/Core/Grain.cs 中Grain被定义为public abstract partial class Grain : IGrainBase, IAddressable该基类是所有 Grain 类的抽象基类它同时实现了IGrainBase与IAddressable并向子类暴露了与运行时交互的关键能力GrainContext当前 Grain 激活的运行时上下文GrainReference指向本 Grain 自身的引用GrainFactory用于获取其他 Grain 引用的工厂对象ServiceProvider由运行时托管的IServiceProvider可用于依赖注入。从源码注释可以确认Grain基类不应该被手动 new——它的构造函数用于运行时激活客户端代码应当通过GrainFactory属性来获取 Grain 引用。HelloGrain对接口的实现非常简单接收一个greeting字符串返回$Hello, {greeting}!。这里没有任何状态、持久化或并发控制但它已经是一个合法的、可以被 Orleans 运行时托管和调度的 Grain 了。第三步用 IGrainFactory 获取 Grain 引用Grain 接口与实现就绪后下一步是获取一个 Grain 引用。在 Program.cs 中// Get the grain factory var grainFactory host.Services.GetRequiredServiceIGrainFactory(); // Get a reference to the HelloGrain grain with the key friend var friend grainFactory.GetGrainIHelloGrain(friend);这里有两个关键概念IGrainFactory由 Orleans 运行时注入到宿主服务容器中因此可以直接从host.Services通过GetRequiredServiceIGrainFactory()取出GetGrainTGrainInterface(friend)返回的只是一个「引用」它并没有立即创建或加载任何 Grain 实例而是一个携带了接口类型与主键friend的可寻址句柄。在 src/Orleans.Core.Abstractions/Core/IGrainFactory.cs 中可以看到GetGrain的扩展方法实现public static TGrainInterface GetGrainTGrainInterface(this IGrainFactory grainFactory, IdSpan grainPrimaryKey) where TGrainInterface : IGrain { ArgumentNullException.ThrowIfNull(grainFactory); return grainFactory.GetGrain(typeof(TGrainInterface), grainPrimaryKey).AsReferenceTGrainInterface(); }它最终通过grainFactory.GetGrain(typeof(TGrainInterface), grainPrimaryKey)构造内部 GrainId并转换为强类型引用。由于IHelloGrain继承自IGrainWithStringKey这里使用字符串friend作为主键。字符串键的取值完全自由——示例用friend但任何字符串如用户名、房间号、订单号都可以用来定位一个独立的 Grain 实例。第四步调用 Grain 方法并观察激活拿到引用之后调用就与普通异步方法无异// Call the grain and print the result to the console var result await friend.SayHello(Good morning!); Console.WriteLine($ {result} );运行后控制台会打印Hello, Good morning!!。这里有一个值得注意的运行时行为首次调用friend.SayHello(...)时Orleans 才真正为friend这个主键在集群中实例化激活HelloGrain。在整个过程中开发者不需要手动管理 Grain 的生命周期Orleans 按需激活 Grain并在其空闲时自动停用deactivate对同一条消息的处理在 Orleans 的调度模型下天然串行化避免并发冲突。这正是 Orleans 作为 .NET 云原生框架的核心价值——把分布式对象的定位、激活、生命周期与并发控制统统托管起来。第五步配置本地开发集群Program.cs中关于 Orleans 的配置只有一行using var host new HostBuilder() .UseOrleans(builder builder.UseLocalhostClustering()) .Build();HostBuilder 与 UseOrleans该程序使用 .NET 通用主机HostBuilder构建应用并通过UseOrleans扩展方法把 Orleans 运行时接入主机生命周期。host.StartAsync()会启动 SiloServer 节点host.StopAsync()在用户按下回车后触发优雅停机。UseLocalhostClustering 的适用场景UseLocalhostClustering()让 Silo 使用localhost 集群——即单个 Silo 既扮演集群成员又承担网关角色整个「集群」运行在本机。这是为开发与测试场景设计的开箱即用配置无需任何外部依赖如数据库、Consul、ZooKeeper 等非常适合快速验证 Grain 逻辑。仓库中对UseLocalhostClustering的客户端变体实现在 src/Orleans.Core/Core/ClientBuilderExtensions.cs其重载支持自定义网关端口、serviceId与clusterId。这也说明了 Orleans 开发中「先本地单机验证、再接入真实集群存储」的典型路径。需要指出的是localhost 集群只适合单机开发。一旦需要多 Silo 部署或跨进程通信就需要为集群配置真实的 Membership 提供程序如 Azure Storage、AdoNet、Consul、ZooKeeper、DynamoDB 等仓库 src 目录下的多个Orleans.Clustering.*项目即是这些提供程序的实现。项目文件与依赖目标框架与包引用HelloWorld.csproj 的内容如下Project SdkMicrosoft.NET.Sdk PropertyGroup TargetFrameworknet10.0/TargetFramework OutputTypeExe/OutputType ImplicitUsingsenable/ImplicitUsings Nullableenable/Nullable ServerGarbageCollectiontrue/ServerGarbageCollection /PropertyGroup ItemGroup PackageReference IncludeMicrosoft.Orleans.Server / PackageReference IncludeMicrosoft.Extensions.Hosting / PackageReference IncludeMicrosoft.Extensions.DependencyInjection / /ItemGroup /Project要点说明net10.0示例面向 .NET 10运行前需要安装 .NET 10 SDK 或更高版本Microsoft.Orleans.Server核心依赖包它聚合了 Orleans Silo 侧所需的全部运行时组件含 Core、Runtime、CodeGenerator、Serialization 等让单个项目即可启动完整的 SiloMicrosoft.Extensions.Hosting/Microsoft.Extensions.DependencyInjection提供HostBuilder与 DI 容器ServerGarbageCollection启用服务器 GC符合服务端长时间运行场景的常见配置。集中版本管理Directory.Packages.props 采用了Central Package Management集中包版本管理Project PropertyGroup ManagePackageVersionsCentrallytrue/ManagePackageVersionsCentrally CentralPackageTransitivePinningEnabledtrue/CentralPackageTransitivePinningEnabled /PropertyGroup ItemGroup PackageVersion IncludeMicrosoft.Extensions.DependencyInjection Version10.0.5 / PackageVersion IncludeMicrosoft.Extensions.Hosting Version10.0.5 / PackageVersion IncludeMicrosoft.Orleans.Server Version10.2.2 / /ItemGroup /Project这样HelloWorld.csproj中的PackageReference无需写版本号所有包版本统一在中央文件中维护便于多项目解决方案保持一致。示例对应的 Orleans 版本为10.2.2。构建与运行前置条件本示例使用 C# 编写并面向 .NET 10需要安装.NET 10 SDK 或更高版本。命令行方式进入 samples/HelloWorld 目录后直接运行dotnet run也可以显式指定项目文件dotnet run --project samples/HelloWorld/HelloWorld.csproj仓库还提供了开箱即用的脚本Windowsrun.cmd内部执行dotnet run --project %~dp0HelloWorld.csprojLinux/macOSrun.sh内部执行dotnet run --project $(dirname $0)/HelloWorld.csproj。Visual Studio 方式打开 HelloWorld.sln 解决方案或直接打开HelloWorld.csproj项目文件按F5以调试方式运行或按CtrlF5直接运行。预期输出运行成功后控制台将打印Hello, Good morning!!随后显示Orleans is running. Press Enter to terminate...等待用户按键后执行host.StopAsync()优雅停机。从 Hello World 到真实项目这个示例虽小却完整覆盖了 Orleans 应用的三个基本构件接口契约— 实现逻辑— 调用入口。以此为起点可以沿仓库中的其他示例继续深入BasicClustering使用 AppHost 编排的多项目集群示例BankAccount账户转账演示状态持久化与多 Grain 交互ChatRoom演示流式消息与观察者模式Voting较完整的 Web Grain 持久化应用。如果需要回顾整个仓库中其余示例的组织方式可参阅 samples/README.md。对于 Orleans 框架本身的源码级细节src/Orleans.Core.Abstractions/Core 下的IGrain.cs、Grain.cs、IGrainFactory.cs都是很好的切入点。小结本文从 samples/HelloWorld 这个官方入门示例出发完整梳理了Grain 接口如何通过IGrainWithStringKey声明主键类型Grain 实现如何通过继承Grain基类获得运行时能力IGrainFactory.GetGrain如何构造「引用」而非立即创建实例UseLocalhostClustering如何支撑开发期的单机集群项目文件、依赖管理与dotnet run运行方式首次调用触发按需激活、空闲自动停用的生命周期语义。把这一段 Hello World 跑通你就已经掌握了 Orleans 中最核心的编程模型——剩下的都是在它之上叠加状态、持久化、流、事务与集群能力。赞分享后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载相关推荐workerd 的 ESM Hello World 示例从 config.capnp 配置到本地运行全解析workerd 的 ESM Hello World 示例从 config.capnp 配置到本地运行全解析 workerd 是驱动 Cloudflare Wo后端语言运行时WebAssemblycareer-ops配置文件详解自定义AI求职系统的完整指南career ops配置文件详解自定义AI求职系统的完整指南 你是否正在使用AI求职系统career ops但想要更精细地控制它的行为 这篇 care人工智能AI 应用AI 技能CRMEB Java商城API接口全攻略从调用示例到自定义接口开发CRMEB Java商城API接口全攻略从调用示例到自定义接口开发 CRMEB Java商城是一款基于SpringBoot Maven Swagger后端前端电商上一篇颠覆级自动驾驶评估基准Bench2Drive的闭环革命下一篇iCraft Editor与Vue.js集成如何快速在Vue项目中嵌入3D架构图场景创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考