多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Microsoft.Orleans.Templates 项目模板使用指南:从 `dotnet new orleans` 到完整集群应用

Microsoft.Orleans.Templates 项目模板使用指南:从 `dotnet new orleans` 到完整集群应用 后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载导读本文围绕仓库 templates/Microsoft.Orleans.Templates 中的官方项目模板展开完整讲解orleans与orleans-web两套模板的安装、参数、生成结构、底层实现与本地运行方式。读完本文你将掌握如何用一条dotnet new命令生成契约—实现—Silo—外部客户端—AppHost五项目架构的 Aspire 编排解决方案也能理解共置co-host模式的 ASP.NET Core 应用如何通过 HTTP 端点调用 Grain以及这两套模板在部署到多节点生产环境前需要替换哪些开发期配置。模板包概览一套命令两种应用形态Microsoft.Orleans.Templates是 Orleans 官方的dotnet new模板包为最常见的 Orleans 应用布局提供两种脚手架。从包的 Microsoft.Orleans.Templates.csproj 可以看到PackageId为Microsoft.Orleans.TemplatesPackageType为Template模板内容打包时会把两个模板清单templates/orleans/.template.config/template.json与templates/orleans-web/.template.config/template.json中的 Orleans 版本占位符替换为随包发布的真实版本也就是说模板默认引用的 Orleans 版本就是模板包随附的版本含预发布版本避免出现模板装好了、包版本对不上的经典问题。两种模板的定位差异非常清晰orleansOrleans application生成一个完整的解决方案OrleansApp.slnx包含五个项目并使用 Aspire 编排 Silo、外部客户端以及 Azurite 模拟的 Azure 存储。适合作为正式分布式应用的起点。orleans-webOrleans ASP.NET Core application生成一个共置 Silo 的 ASP.NET Core 单项目通过 HTTP 端点对外暴露 Grain 能力。适合快速验证 Grain 逻辑或构建单体化交付的前端入口。安装模板包只需一条命令dotnet new install Microsoft.Orleans.Templates安装后可以通过dotnet new orleans -h/dotnet new orleans-web -h查看完整参数说明。创建第一个多项目 Orleans 应用dotnet new orleans生成一个名为MyOrleansApp的 Aspire 解决方案将 Grain 契约、Grain 实现、Silo、外部客户端与 AppHost 拆分到独立项目中dotnet new orleans --name MyOrleansApp生成的项目结构与分工生成的解决方案包含五个项目以 templates/orleans 目录下的模板为基准项目职责关键依赖MyOrleansApp.AppHostAspire 编排入口定义 Orleans 资源与 Azurite 存储资源Aspire.Hosting.Azure.Storage、Aspire.Hosting.Orleans见 OrleansApp.AppHost.csprojMyOrleansApp.Contracts定义 Grain 接口被调用方与实现方共享Microsoft.Orleans.Sdk见 OrleansApp.Contracts.csprojMyOrleansApp.Grains实现 Grain 接口Microsoft.Orleans.Runtime、Microsoft.Orleans.SdkMyOrleansApp.Silo承载 Orleans 运行时与 Grain 激活Microsoft.Orleans.Server、Microsoft.Orleans.Clustering.AzureStorage、Microsoft.Orleans.Persistence.AzureStorageMyOrleansApp.Client外部客户端进程连接集群并调用 GrainMicrosoft.Orleans.Client、Microsoft.Orleans.Clustering.AzureStorage依赖方向严格单向Client 只引用 Contracts不引用 Grains 实现程序集Silo 引用 GrainsGrains 再引用 Contracts。这种调用方只见接口、不见实现的边界是 Orleans 官方推荐的分层方式便于后续将 Grain 实现替换为其他程序集或进行独立部署。模板清单 template.json 中的primaryOutputs列出了生成的主产物.slnx、aspire.config.json以及五个项目的.csproj并在postActions中默认执行dotnet restore可通过--skip-restore true跳过。模板自带的示例 Grain契约侧IHelloGrain.cs使用字符串键标识 Grainnamespace OrleansApp.Contracts; public interface IHelloGrain : IGrainWithStringKey { Taskstring SayHello(string name); }实现侧HelloGrain.cs通过[PersistentState(hello, Default)]把一个int计数状态挂接到名为Default的持久化存储上using Orleans.Runtime; using OrleansApp.Contracts; namespace OrleansApp.Grains; public sealed class HelloGrain( [PersistentState(hello, Default)] IPersistentStateint callCount) : Grain, IHelloGrain { public async Taskstring SayHello(string name) { callCount.State; await callCount.WriteStateAsync(); return $Hello, {name}! Call count: {callCount.State}.; } }SayHello每次调用都会自增调用计数并写回存储返回值类似Hello, Ada! Call count: 3.。这个示例把状态持久化 集群发现两个 Orleans 核心能力一并演示了出来是理解模板底层依赖的最佳入口。五个项目如何协作从 AppHost 到 ClientMyOrleansApp.AppHost的 Program.cs 是整套编排的核心var builder DistributedApplication.CreateBuilder(args); var storage builder.AddAzureStorage(orleans-storage) .RunAsEmulator(); var clustering storage.AddTables(clustering); var grainState storage.AddBlobs(grain-state); var orleans builder.AddOrleans(orleans) .WithClustering(clustering) .WithGrainStorage(Default, grainState); var silo builder.AddProjectProjects.OrleansApp_Silo(silo) .WithReference(orleans) .WaitFor(clustering) .WaitFor(grainState); builder.AddProjectProjects.OrleansApp_Client(client) .WithReference(orleans.AsClient()) .WaitFor(clustering) .WaitFor(silo); builder.Build().Run();这里的关键 API 与仓库 docs/site/src/content/docs/host/aspire-integration.md 中总结的 Aspire Orleans 集成方法一一对应AddOrleans(name)定义一个 Orleans 集群资源WithClustering(resource)选择集群成员管理与网关提供者这里用 Azure TableWithGrainStorage(name, resource)添加命名 Grain 存储这里把名为Default的存储绑定到 Azure BlobAsClient()为 Client 项目创建仅客户端视角的集群引用WithReference(orleans)把 Orleans 配置注入到项目。注意 AppHost 把clusteringTable与grain-stateBlob都挂到同一个orleans-storage资源下.RunAsEmulator()表示本地开发时启动 Azurite 模拟器。仓库文档明确提示.RunAsEmulator()只是本地开发选择发布部署时必须把 Azure 存储资源绑定到真实账户并在部署环境中配置身份与访问权限切勿把模拟器配置照搬进生产 AppHost。Silo 项目OrleansApp.Silo/Program.cs则注册与资源同名的 keyed Aspire 客户端然后调用无参的UseOrleans()using Microsoft.Extensions.Hosting; var builder Host.CreateApplicationBuilder(args); builder.AddKeyedAzureTableServiceClient(clustering); builder.AddKeyedAzureBlobServiceClient(grain-state); builder.UseOrleans(); await builder.Build().RunAsync();这是 Aspire Orleans 集成的一个硬性约束资源引用只负责注入配置应用项目必须为每个被 Orleans 消费的后端资源注册匹配的 keyed 客户端如AddKeyedAzureTableServiceClient且 key 名称要与 AppHost 中的资源名完全一致。AppHost 注入的是完整的Orleans配置层级Silo 会从中绑定集群标识、端点、聚类、提醒、Grain 存储与目录配置。Client 项目OrleansApp.Client/Program.cs与 Silo 一样注册clustering的 keyed 客户端随后调用无参的UseOrleansClient()在主机启动后从依赖注入解析IGrainFactory获取 Grain 引用并调用using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using OrleansApp.Contracts; var builder Host.CreateApplicationBuilder(args); builder.AddKeyedAzureTableServiceClient(clustering); builder.UseOrleansClient(); using var host builder.Build(); await host.StartAsync(); var grainFactory host.Services.GetRequiredServiceIGrainFactory(); var friend grainFactory.GetGrainIHelloGrain(friend); Console.WriteLine(await friend.SayHello(friend)); await host.StopAsync();这个流程与仓库中 build-your-first-orleans-app.md 教程描述的Client 通过GetGrainIHello()拿到的是逻辑引用调用时由 Orleans 路由到 Silo 网关并按需激活 Grain完全一致。值得一提的是模板走的是外部客户端模式前端与 Silo 各自独立进程便于独立扩缩容、部署与安全隔离若只需快速迭代参考 client.md 中共置客户端一节的选择建议无隔离需求时优先共置。构建与运行构建解决方案dotnet build启动整个应用从解决方案根目录执行dotnet run --project MyOrleansApp.AppHost运行前置条件有两个来自 templates/orleans/README.md 与主 README.md本机必须运行容器运行时Docker 等因为 Aspire 需要启动 Azurite 模拟器已安装与 Aspire 版本匹配的 .NET SDK 与 Aspire 支持工具链。AppHost 启动后按先后顺序拉起 Azurite → Silo → ClientWaitFor保证了依赖就绪顺序。运行期间终端会打印 Aspire Dashboard 的 URL打开它即可查看资源状态与日志。Client 正常运行会输出类似Hello, friend! Call count: 1.计数来自 Azure Blob 中的持久化状态Silo 与 Client 都通过 Azure Table 完成集群发现。发布时需要把 AppHost 中的 Azure 存储资源替换为目标环境的真实资源。创建共置 Silo 的 Web 应用dotnet new orleans-weborleans-web模板生成一个 ASP.NET Core 应用它在同一进程中共置一个 Orleans Silo并通过 HTTP 端点暴露 Grain 能力dotnet new orleans-web --name MyOrleansWebApp生成的代码如何工作模板生成的 Program.cs 只有十余行却完成了宿主 Silo 端点三件事using OrleansWebApp; var builder WebApplication.CreateBuilder(args); builder.Host.UseOrleans(siloBuilder siloBuilder.UseLocalhostClustering()); var app builder.Build(); app.MapGet(/, () Results.Redirect(/hello/world)); app.MapGet(/hello/{name}, async (string name, IGrainFactory grainFactory) { var grain grainFactory.GetGrainIHelloGrain(name); return await grain.SayHello(name); }); await app.RunAsync();UseOrleans(...)注册 Silo同时会注册共置的IClusterClient/IGrainFactory到依赖注入容器对应仓库文档 client.md 中Co-hosted clients一节共置客户端直接利用 Silo 的集群知识不需要独立网关进程UseLocalhostClustering()配置仅限本机单节点开发的回环网络聚类与开发期集群详见 local-development-configuration.md端点处理器从依赖注入解析IGrainFactory用路由参数name作为字符串键获取IHelloGrain引用再把SayHello的异步结果直接作为 HTTP 响应返回。契约与实现同处一个项目IHelloGrain.cs 与 HelloGrain.cs// IHelloGrain.cs namespace OrleansWebApp; public interface IHelloGrain : IGrainWithStringKey { Taskstring SayHello(string name); }// HelloGrain.cs namespace OrleansWebApp; public sealed class HelloGrain : Grain, IHelloGrain { public Taskstring SayHello(string name) Task.FromResult($Hello, {name}!); }该模板不引入持久化存储Grain 是无状态实现直接返回问候文本适合快速体验HTTP → Grain → 响应的最小闭环。运行与调用端点运行dotnet run调用生成的端点curl http://localhost:5000/hello/Ada返回Hello, Ada!launchSettings.jsonProperties/launchSettings.json预置了http://localhost:5000与启动即打开/hello/world的行为根路径/会自动重定向到/hello/world。模板的框架与 Orleans 版本选择两个模板默认目标框架均为.NET 10net10.0同时保留了对 .NET 8 的兼容选项。传--framework net8.0即可切换dotnet new orleans --name MyOrleansApp --framework net8.0模板引用随包发布的 Orleans 版本含预发布版本。若要固定到某个具体版本用--orleans-version指定dotnet new orleans-web --name MyOrleansWebApp --orleans-version 10.2.2从两份 template.json 的symbols定义可以确认完整的参数表参数类型默认值说明frameworkchoicenet10.0生成项目的目标框架可选net10.0/net8.0orleansVersiontext随包版本的占位符开发期默认10.0.0-dev打包时替换为真实版本Orleans 包版本--orleans-version传入aspireVersiontext13.5.0仅orleans模板Aspire 包与 AppHost SDK 版本通过__ASPIRE_VERSION__替换skipRestoreboolfalse设为true跳过模板创建后的自动dotnet restore这些占位符会在生成时替换到工程文件中orleans模板的 Directory.Packages.props 用$(OrleansVersion)统一约束Microsoft.Orleans.*系列包版本、用$(AspireVersion)约束Aspire.*系列包版本并开启ManagePackageVersionsCentrally集中版本管理AppHost 的 csproj 则通过SdkAspire.AppHost.Sdk/__ASPIRE_VERSION__引用对应版本的 AppHost SDK。orleans-web模板的 Directory.Packages.props 结构更简单只需约束Microsoft.Orleans.Server一个包。若需其他 Orleans 版本应在生成后手动修改这些集中版本管理文件。两个模板的依赖差异对比依赖orleans模板orleans-web模板Microsoft.Orleans.Server仅 Silo 项目单项目Microsoft.Orleans.ClientClient 项目无共置客户端Microsoft.Orleans.Clustering.AzureStorageSilo Client无localhost 聚类Microsoft.Orleans.Persistence.AzureStorageSilo无Aspire.Hosting.Orleans/Aspire.*AppHost 与各项目无ServerGarbageCollectionSilo / Grains 项目启用启用从 csproj 可见Silo 与 Web 项目都显式开启ServerGarbageCollection——这与仓库 typical-configurations.md 中生产配置应显式选择 CPU、内存、Server GC的建议一致模板在生成时就把这项生产导向的配置带上了。AI 辅助开发与 Copilot 指引生成的项目中还会包含.github/instructions/orleans.instructions.md文件其作用是指引 GitHub Copilot 跳转到当前版本的 Orleans 文档与 API 参考使 AI 助手在编写、审查 Grain 代码时能基于正确的 API 语义作答。因此在使用dotnet new orleans生成的仓库后若启用 Copilot 类工具可以直接受益于这份随项目分发的上下文指引无需手动配置额外的 Agent 规则。从开发模板走向生产部署模板定位是快速起步的脚手架因此开发期配置与生产部署之间有明显差距官方文档在多个位置反复强调了这一点orleans模板使用Azurite 模拟器承载聚类Azure Table与 Grain 状态Azure Blob模拟器数据不具备真实持久性与可用性仅适合本地验证。生产环境必须改用真实 Azure 存储账户或其他平台级托管服务并用工作负载/托管身份注入凭据。orleans-web模板使用localhost clustering单节点开发聚类成员表保存在主 Silo 内存中进程退出即失效且只能支撑单机开发。仓库文档 local-development-configuration.md 明确警告不要把 localhost、静态、开发期、内存或模拟器支撑的提供者当作生产基础设施。若计划部署多实例需要按仓库 typical-configurations.md 给出的生产配置检查清单逐项调整选择平台支持的持久化聚类提供者如 Azure Table、Redis、DynamoDB、ADO.NET、Consul、ZooKeeper 等各包见 src 目录下的对应实现如 Orleans.Clustering.AzureStorage、Orleans.Clustering.Consul设置稳定不变的ServiceId与按环境隔离的ClusterId配置所有 Silo 与 Client 均可路由的通告地址按实际使用的功能添加持久化存储、提醒、流与 Grain 目录提供者聚类提供者与存储/提醒提供者无需同源可分别按持久性、延迟、运维与成本选择通过部署环境注入凭据配置健康检查/就绪探针、遥测导出、优雅终止、CPU/内存与 Server GC。聚类提供者选择参考Azure 部署可用 Azure Table 做聚类、Blob/Table 做 Grain 状态AWS 可用 DynamoDB数据库为中心的部署可用 ADO.NETRedis、Cosmos、Consul、ZooKeeper 各有对应包。需要多 Silo 时可以继续沿用 Aspire 编排用.WithReplicas(n)拉起多个 Silo 副本以验证成员变更与故障转移但同样要把容器/模拟器资源替换为托管服务。小结Microsoft.Orleans.Templates用两条命令覆盖了 Orleans 应用最常见的两种拓扑orleans提供面向分布式部署的Contracts / Grains / Silo / Client / AppHost五项目 Aspire 解决方案开箱即带 Azurite 聚类的集群发现与 Blob 持久化orleans-web提供单进程共置的 HTTP 入口适合快速验证与轻量交付。二者默认 .NET 10、支持--framework/--orleans-version/--aspire-version精确控制版本并通过集中版本管理与随包替换机制规避版本漂移。把它们当作本地开发样板而非生产配置模板按照官方配置指南逐项替换为持久化提供者与真实资源即可平滑过渡到多节点生产集群。赞分享后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载相关推荐Blazor项目创建终极指南从dotnet new到自定义模板的完整教程Blazor是一个革命性的Web框架让你能够使用C 而不是JavaScript来构建交互式Web UI。无论你是.NET开发者想要进入前端开发还是希望统一前前端Web框架将 Orleans 应用部署到 Azure Container Apps从本地集群到生产可观测集群的完整实战指南将 Orleans 应用部署到 Azure Container Apps从本地集群到生产可观测集群的完整实战指南 本文以 production applica后端微服务使用 Chocolatey msi.template 模板创建 MSI 包从 choco new 到 shim 生成的完整指南使用 Chocolatey msi.template 模板创建 MSI 包从 choco new 到 shim 生成的完整指南 导读 本文以 Chocolat包管理器CLI开发工具上一篇使用 Prisma 引导 React GraphQL 全栈应用react-fullstack-basic 快速上手实战指南下一篇DeepTutor当AI成为你的终身学习伴侣教育会发生什么改变创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表