Orleans集群及Placement设置

服务端界面使用相同的clusterid和serviceid,相同ip地址,不同网关端口号和服务端口号,启动两个silo服务,并使用MySql数据库做Silo间信息同步,实现集群。

 silo服务启动代码如下(从nuget下载Microsoft.Orleans.Clustering.AdoNet库):

            var clusterID = ClusterID;var serviceID = ServiceID;var siloPort = SiloPort;var gatewayPort = GatewayPort;//本地集群方式部署var primarySiloEndPoint = new IPEndPoint(IPAddress.Parse(PrimarySiloIPAddr), siloPort);var silo = new HostBuilder().UseOrleans(builder =>{builder.UseAdoNetClustering(options =>{options.Invariant = GlobalValueDefinition.MySqlInvariant;options.ConnectionString = GlobalValueDefinition.MySqlConnection;}).Configure<ClusterOptions>(options =>{options.ClusterId = clusterID;options.ServiceId = serviceID;}).ConfigureEndpoints(siloPort: siloPort, gatewayPort: gatewayPort).ConfigureLogging(logging => logging.AddConsole()).UseDashboard(options =>{options.Username = "henreash";options.Password = "123456";options.Host = "*";options.Port = 8081;})//.AddMemoryStreams(GlobalValueDefinition.StreamProviderName) //unget引入 Microsoft.Orleans.Streaming.AddMemoryGrainStorage(GlobalValueDefinition.GrainStorageName).AddPlacementDirector<MyPlacementStrategy>(sp=>new MyPlacementDirector())#region 拦截器.AddIncomingGrainCallFilter(async context =>{if (context.InterfaceMethod.Name == nameof(IHello.HelloCallFilter)){RequestContext.Set("CallFilterValue", "this value was added by the filter");}await context.Invoke();if (context.InterfaceMethod.Name == nameof(IHello.HelloCallFilter)){context.Result = $"{context.Result},added by the filter  {clusterID} - {serviceID}  - {gatewayPort}";}});#endregion#region 使用NewtonJson做序列化引擎//需引用Microsoft.Orleans.Serialization.NewtonsoftJson包builder.Services.AddSerializer(serializerBuilder =>{serializerBuilder.AddNewtonsoftJsonSerializer(isSupported: type => true/*type.Namespace.StartsWith("Example.Namespace")*/);});#endregion}).Build();await silo.RunAsync();

MySql数据库常量定义:

        public const string MySqlInvariant = "MySql.Data.MySqlClient";public const string MySqlConnection = "server=localhost;user id=root;database=orleans_test;port=3306;password=xxxxxx";

 

客户端启动代码(从nuget下载Microsoft.Orleans.Clustering.AdoNet库):

            var clusterID = ClusterID;var serviceID = ServiceID;var serviceID02 = ServiceID02;var PRIMARY_SILO_IP_ADDRESS = IPAddress.Parse(textBox_IPAddr.Text);#region ADO服务器群集模式连接host01 = Host.CreateDefaultBuilder().UseOrleansClient(clientBuilder =>clientBuilder.UseAdoNetClustering(options => {options.Invariant = GlobalValueDefinition.MySqlInvariant;options.ConnectionString = GlobalValueDefinition.MySqlConnection;}).Configure<ClusterOptions>(options =>{options.ClusterId = clusterID;options.ServiceId = serviceID;})#region Stream测试.AddMemoryStreams(GlobalValueDefinition.StreamProviderName)#endregion).Build();await host01.StartAsync();client01 = host01.Services.GetRequiredService<IClusterClient>();#endregion#region 订阅friend1 = client01.GetGrain<IHello>("user1");friend2 = client01.GetGrain<IHello>("user2");Chat c = new Chat();(c as IChatNotify).ReceiveAct += (text, data) => ShowLog($"user1 callback {text} dateLen={data.Length}");chat = client01.CreateObjectReference<IChat>(c);await friend1.Subscribe(chat);Chat c02 = new Chat();(c02 as IChatNotify).ReceiveAct += (text, data) => ShowLog($"user2 callback {text} dateLen={data.Length}");chat02 = client01.CreateObjectReference<IChat>(c02);await friend2.Subscribe(chat02);#endregion

客户端只需指定clusterid、serviceid、mysql数据库连接字符串即可。测试过程中发现这种模式有几秒延时,服务端启动后立即启动客户端并进行连接,可能出现某个silo服务无法连接的情况。

 Placement:

比如特定业务场景,服务器上部署了硬件外设,希望每个silo服务器都启动一个grain实例,可使用Placement机制进行制约;

首先定义Placement规则:

    public class MyPlacementDirector : IPlacementDirector{public Task<SiloAddress> OnAddActivation(PlacementStrategy strategy, PlacementTarget target, IPlacementContext context){var userID = target.GrainIdentity.Key.ToString();var silos = context.GetCompatibleSilos(target).ToArray();SiloAddress siloAddress = silos.First();if (userID == "user1")siloAddress = silos?.FirstOrDefault(x=>x.Endpoint.Port == 11111) ?? siloAddress;else if(userID == "user2")siloAddress = silos?.FirstOrDefault(x => x.Endpoint.Port == 11112) ?? siloAddress;return Task.FromResult(siloAddress);}}[Serializable]public sealed class MyPlacementStrategy: PlacementStrategy{}[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]public sealed class MyPlacementStrategyAttribute : PlacementAttribute{public MyPlacementStrategyAttribute() : base(new MyPlacementStrategy()) { }}

 上面代码做了简单约定,grain user1在端口11111的silo上创建,user2在端口11112的silo上创建。

Grain定义类上增加PlacementAttribute注解,服务端启动silo服务时注册自定义Placement规则:

另外Stream会根据StreamID创建额外的Grain,实际应用需注意。

双向通信过程中,grain向客户端发消息,数据量几十K效率还可以,过大(几兆)导致卡顿。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】 IPC 进程间通信(三)(消息队列 信号量)

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 一、消息队列 &#x1f48c;…

Docker:镜像构建 DockerFile

Docker&#xff1a;镜像构建 DockerFile 镜像构建docker build DockerfileFROMCOPYENVWORKDIRADDRUNCMDENTRYPOINTUSERARGVOLUME 镜像构建 在Docker官方提供的镜像中&#xff0c;大部分都是基础镜像&#xff0c;他们只提供某个简单的功能&#xff0c;如果想要一个功能更加丰富…

遥控器数图控链路系统核心技术+算法详解

一、核心技术 无线通信技术 遥控器数图控链路系统主要基于无线通信技术进行数据传输。通过特定的调制、编码和信号处理技术&#xff0c;将遥控器的操作指令转化为无线电信号&#xff0c;并传输给被控制设备。被控制设备接收到信号后&#xff0c;再将其解码为可识别的指令&…

Kafka 源码 KRaft 模式本地运行

KRaft&#xff08;Kafka Raft Metadata mode&#xff09;&#xff0c;从版本 2.8.0 开始作为测试特性引入&#xff0c;并在后续版本中持续得到改进和增强。 KRaft 模式是指 Kafka 使用 Raft 协议来管理集群元数据的一种运行模式&#xff0c;这标志着 Kafka 向去除对 ZooKeeper …

Android下的系统调用 (syscall),内联汇编syscall

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 什么是系统调用 (syscall) 系统调用是操作系统提供给应用程序的一组接口&#xff0c;允许用户空间程序与内核进行交互。 在 Android&#xff08;基于 Linux …

RAGulator:如何识别和缓解大模型所谓的“忠实幻觉”

RAGulator&#xff0c;一个轻量级的、用于检测RAG系统中语义上与上下文不符&#xff08;OOC&#xff09;的LLM生成文本的检测器 论文链接:https://arxiv.org/abs/2411.03920 论文概述 实时检测大型语言模型&#xff08;LLM&#xff09;生成的与上下文不符的输出问题&#xff…

Git核心概念

目录 版本控制 什么是版本控制 为什么要版本控制 本地版本控制系统 集中化的版本控制系统 分布式版本控制系统 认识Git Git简史 Git与其他版本管理系统的主要区别 Git的三种状态 Git使用快速入门 获取Git仓库 记录每次更新到仓库 一个好的 Git 提交消息如下&#…

leetcode82:删除排序链表中的重复节点||

给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5]示例 2&#xff1a; 输入&#xff1a;head [1,1,1,2…

基于SpringBoot的Java教学支持系统开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理教学辅助平台的相关信息成为必然。开发合适…

python3的基本数据类型:可变集合的用法

一. 简介 前面学习了 python3中的一种基本数据类型-集合&#xff0c;文章如下&#xff1a; python3的基本数据类型&#xff1a;集合的创建与分类-CSDN博客 本文继续学习 Python3中的集合&#xff0c;主要学习 可变集合的用法。 二. python3的基本类型&#xff1a;可变集合的…

【Linux系列】 环境配置文件合并的艺术:从`.env`到`.env.combined`

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C/C++语言基础--C++模板与元编程系列五(可变惨模板,形参包展开,折叠表达式)

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 模板与元编程是C的重要特点&#xff0c;也是难点&#xff0c;本人预计将会更新10期左右进行讲解&#xff0c;这是第五期&#xff0c;讲解可变惨模板&#xff0c;形参包展开&#xff0c;折叠表达式等&#x…

Redis设计与实现 学习笔记 第十六章 Sentinel

Sentinel&#xff08;哨岗、哨兵&#xff09;是Redis的高可用性&#xff08;high availability&#xff09;解决方案&#xff1a;由一个或多个Sentinel实例&#xff08;instance&#xff09;组成的Sentinel系统可以监视任意多个主服务器&#xff0c;以及这些主服务器属下的从服…

贪心算法day05(k次取反后最大数组和 田径赛马)

目录 1.k次取反后最大化的数组和 2.按身高排序 3.优势洗牌 1.k次取反后最大化的数组和 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 代码&#xff1a; class Solution {public int largestSumAfterKNegations(int[] nums, int k) {//如…

易语言加载dll模拟windows鼠标轨迹移动

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

Go语言的常用内置函数

文章目录 一、Strings包字符串处理包定义Strings包的基本用法Strconv包中常用函数 二、Time包三、Math包math包概述使用math包 四、随机数包&#xff08;rand&#xff09; 一、Strings包 字符串处理包定义 Strings包简介&#xff1a; 一般编程语言包含的字符串处理库功能区别…

Springboot+Vue+mysql前后端分离的Java项目部署教程

参考了网上许多文章&#xff0c;有的使用的是nginx&#xff0c;eclipse&#xff0c;其实只要是数据库或者java的软件基本都大同小异。 本人使用phpstudy对项目进行部署&#xff0c;亲测有效。 需要的软件&#xff1a; 1.Node.js安装&#xff08;ps&#xff1a;这一步我也不知道…

Linux系统程序设计--2. 文件I/O

文件I/O 标准C的I/O FILE结构体 下面只列出了5个成员 可以观察到&#xff0c;有些函数没有FILE类型的结构体指针例如printf主要是一些标准输出&#xff0c;因为其内部用到了stdin&#xff0c;stdout&#xff0c;stderr查找文件所在的位置:find \ -name stat.h查找头文件所…

HarmonyOS Next 实战卡片开发 02

HarmonyOS Next 实战卡片开发 02 卡片开发中&#xff0c;还有一个难点是显示图片。其中分为显示本地图片和显示网络图片 显示本地图片 卡片可以显示本地图片&#xff0c;如存放在应用临时目录下的图片。路径比如 /data/app/el2/100/base/你的项目boundleName/temp/123.png 以…

【C++ 算法进阶】算法提升十一 十二

目录标题 让字符串成为回文串的最少插入次数题目题目分析代码题目题目 字符子串 &#xff08;滑动窗口&#xff09;题目题目分析代码 最长连续子序列 &#xff08;头尾表&#xff09;题目题目分析代码 让字符串成为回文串的最少插入次数 题目 本题为为LC原题 题目如下 题目分…