Orleans初体验
Orleans:
- 是一个跨平台框架,用于构建可靠且可缩放的分散式应用。 分布式应用定义为跨多个进程的应用,通常使用对等通信来超越硬件边界。
- 从单个本地服务器扩展到了云中数千个分布式、高度可用的应用。
- 将熟悉的概念和 C# 习语扩展到了多服务器环境。
- 在设计上可弹性缩放。 当主机加入群集时,它可以接受新的激活。 当主机退出群集时,该主机上的先前激活将根据需要在其余主机上重新激活。 主机可能会因纵向缩减或计算机故障而退出群集。 Orleans 群集可以纵向缩减为单个主机。 用于启用弹性缩放的相同属性会启用容错。 群集可自动检测故障并快速从故障中恢复。
- 通过提供一组常见的模式和 API,简化分布式应用开发的复杂性。
- 熟悉单一服务器应用开发的开发人员可以改为构建可复原、可缩放的云原生服务和分布式应用。
- 有时称为“分布式 .NET”。
- 构建云原生应用时选择的框架。
- 可以在支持 .NET 的任意位置运行。 这包括将它托管在 Linux、Windows 和 macOS 上。
- 应用可以部署到 Kubernetes、虚拟机和 PaaS 服务,例如 Azure 应用服务和 Azure 容器应用。
这是官方的解释,不熟悉相关的概念看起来会一脸愣逼,实践才是王道,下面我们就来个初体验:
1、打开VS2022,新建一个ASP.NET Core WebAPI项目;
2、输入项目名称和选择文件夹位置,然后选择以下选项:
.NET Aspire是因为我在解决方案中配了Aspire,可选可不选。
3、安装Microsoft.Orleans.Server Nuget包,如图:
4、用如下代码替换Programs.cs:
1 // <configuration> 2 using Orleans.Runtime; 3 4 var builder = WebApplication.CreateBuilder(args); 5 6 builder.Host.UseOrleans(static siloBuilder => 7 { 8 siloBuilder.UseLocalhostClustering(); 9 siloBuilder.AddMemoryGrainStorage("urls"); 10 }); 11 12 using var app = builder.Build(); 13 // </configuration> 14 15 // <endpoints> 16 app.MapGet("/", static () => "Welcome to the URL shortener, powered by Orleans!"); 17 18 app.MapGet("/shorten", 19 static async (IGrainFactory grains, HttpRequest request, string url) => 20 { 21 var host = $"{request.Scheme}://{request.Host.Value}"; 22 23 // Validate the URL query string. 24 if (string.IsNullOrWhiteSpace(url) && 25 Uri.IsWellFormedUriString(url, UriKind.Absolute) is false) 26 { 27 return Results.BadRequest($""" 28 The URL query string is required and needs to be well formed. 29 Consider, ${host}/shorten?url=https://www.microsoft.com. 30 """); 31 } 32 33 // Create a unique, short ID 34 var shortenedRouteSegment = Guid.NewGuid().GetHashCode().ToString("X"); 35 36 // Create and persist a grain with the shortened ID and full URL 37 var shortenerGrain = 38 grains.GetGrain<IUrlShortenerGrain>(shortenedRouteSegment); 39 40 await shortenerGrain.SetUrl(url); 41 42 // Return the shortened URL for later use 43 var resultBuilder = new UriBuilder(host) 44 { 45 Path = $"/go/{shortenedRouteSegment}" 46 }; 47 48 return Results.Ok(resultBuilder.Uri); 49 }); 50 51 app.MapGet("/go/{shortenedRouteSegment:required}", 52 static async (IGrainFactory grains, string shortenedRouteSegment) => 53 { 54 // Retrieve the grain using the shortened ID and url to the original URL 55 var shortenerGrain = 56 grains.GetGrain<IUrlShortenerGrain>(shortenedRouteSegment); 57 58 var url = await shortenerGrain.GetUrl(); 59 60 // Handles missing schemes, defaults to "http://". 61 var redirectBuilder = new UriBuilder(url); 62 63 return Results.Redirect(redirectBuilder.Uri.ToString()); 64 }); 65 66 app.Run(); 67 // </endpoints> 68 69 // <graininterface> 70 public interface IUrlShortenerGrain : IGrainWithStringKey 71 { 72 Task SetUrl(string fullUrl); 73 74 Task<string> GetUrl(); 75 } 76 // </graininterface> 77 78 // <grain> 79 public sealed class UrlShortenerGrain( 80 [PersistentState( 81 stateName: "url", 82 storageName: "urls")] 83 IPersistentState<UrlDetails> state) 84 : Grain, IUrlShortenerGrain 85 { 86 public async Task SetUrl(string fullUrl) 87 { 88 state.State = new() 89 { 90 ShortenedRouteSegment = this.GetPrimaryKeyString(), 91 FullUrl = fullUrl 92 }; 93 94 await state.WriteStateAsync(); 95 } 96 97 public Task<string> GetUrl() => 98 Task.FromResult(state.State.FullUrl); 99 } 100 101 [GenerateSerializer, Alias(nameof(UrlDetails))] 102 public sealed record class UrlDetails 103 { 104 [Id(0)] 105 public string FullUrl { get; set; } = ""; 106 107 [Id(1)] 108 public string ShortenedRouteSegment { get; set; } = ""; 109 } 110 // </grain>
5、设为启动项目,按F5运行。可以看到启动后自动打开了浏览器访问swagger出错,没关系,我们将网址路径都删掉,保留根目录,回车可看下如下内容:
这说明已经成功运行。
然后我们测试一下功能,如下图我们访问shorten附加一个博客网址,提交后返回了一个缩短的网址:
然后我们访问缩短网址,即跳转到我们之前附加的网址:
第一个奥尔良项目就成功运行了。
如果想了解更多内容,可以访问微软官方文档深入学习:
Orleans 概述 - .NET | Microsoft Learn (https://learn.microsoft.com/zh-cn/dotnet/orleans/overview)