Orleans初体验

news/2024/9/23 11:19:43

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>
View Code

5、设为启动项目,按F5运行。可以看到启动后自动打开了浏览器访问swagger出错,没关系,我们将网址路径都删掉,保留根目录,回车可看下如下内容:

 这说明已经成功运行。

然后我们测试一下功能,如下图我们访问shorten附加一个博客网址,提交后返回了一个缩短的网址:

 然后我们访问缩短网址,即跳转到我们之前附加的网址:

 第一个奥尔良项目就成功运行了。

如果想了解更多内容,可以访问微软官方文档深入学习:

Orleans 概述 - .NET | Microsoft Learn (https://learn.microsoft.com/zh-cn/dotnet/orleans/overview)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/46799.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

9. Mybatis 小技巧

1. #{ } 和 $#{ } 和 ${ } 的区别 #{ }:先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防止sql注入,比较常用。 ${}:先进行sql语句拼接,然后再编译sql语句,底层是Statement实现。存在sql注入现象。只有在需要进行sql语句关键字拼接的情况下才会用到。…

DK盾VPS,您的专属云上堡垒

【探索未来网络的无限可能 —— DK盾VPS,您的专属云上堡垒】 在数字化浪潮中,稳定、高效、安全的网络服务是企业与个人用户追求卓越的关键。DK盾VPS,作为新一代虚拟专用服务器的杰出代表,正以卓越的性能和全方位的安全防护,引领着云服务的新潮流。 【性能卓越,畅享极速体…

Hadoop电商日志数据分析(三)

ETL 1.ETL的重要性 ==> 存在的问题:每个MR作业都去全量读取待处理的原始日志,如果数据量很大,将非常不可取ETL:数据从来源端经过抽取(Extract)、转换(Transform)、加载(Load)至目的端的过程 为什么要ETL:没有必要解析出所有数据,只需要解析出有价值的字段即可。…

C140 线段树分治+01Trie P4585 [FJOI2015] 火星商店问题

视频链接:C140 线段树分治+01Trie P4585 [FJOI2015] 火星商店问题_哔哩哔哩_bilibili C09【模板】可持久化字典树(Trie) - 董晓 - 博客园 (cnblogs.com) P4585 [FJOI2015] 火星商店问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)// 线段树分治 O(nlognlogn) #includ…

Hadoop电商日志数据分析(一)

项目要求 根据电商日志文件,分析: 1 . 统计页面浏览量(每行记录就是一次浏览) 2 . 统计各个省份的浏览量 (需要解析IP) 3 . 日志的ETL操作(ETL:数据从来源端经过抽取(Extract)、转换(Transform)、加载(Load)至目的端的过程)为什么要ETL:没有必要解析出所有数据…

单运放的浮动供电电路的进一步解释讲解

有时候需要运算放大器输出高一些的电压,或者输入高一些的电压,又或者输入输出都高一些。最简单的办法就是使用钞能力,只要钱给够,加上允许的时间够长,那么总可以买到甚至定制到合适的运算放大器。如果使用数量不多,也可以自己搭建分立元件的运算放大器,达到需求的功能。…

LLM大模型: RAG的langchain+向量数据库实现和评估方案

LLM大模型的核心功能之一就是聊天对话(信息检索),RAG的使用必不可少!大致的流程是:用户的query先转成embedding,去向量数据库查询最接近的top K回答;然后这query + top K的回答 + 其他context一起进入LLM,让LLM整合上述所有的信息后给出最终的回复!为了简便、快速地实…

FFmpeg开发笔记(三十二)利用RTMP协议构建电脑与手机的直播Demo

不管是传统互联网还是移动互联网,实时数据传输都是刚需,比如以QQ、微信为代表的即时通信工具,能够实时传输文本和图片。其中一对一的图文通信叫做私聊,多对多的图文通信叫做群聊。 除了常见的图文即时通信,还有实时音视频通信,比如一对一的音频通话、一对一的视频通话等等…