CAP-微服务间通信实践

微服务间通信常见的两种方式

由于微服务架构慢慢被更多人使用后,迎面而来的问题是如何做好微服务间通信的方案。我们先分析下目前最常用的两种服务间通信方案。

gRPC(rpc远程调用)

gRPC-微服务间通信实践

  • 场景:A服务主动发起请求到B服务,同步方式

  • 范围:只在微服务间通信应用

EventBus(基于消息队列的集成事件)

  • 技术:NotNetCore.Cap + Rabbitmq + Database

  • 场景:A服务要在B服务做某件事情后响应,异步方式

  • 实现:B服务在完成某件事情后发布消息,A服务订阅此消息

  • 范围:只在微服务间通信应用

通过对比,两种方式完全不一样。rpc是类似于http请求的及时响应机制,但是比http更轻量、快捷,它更像以前的微软的WCF,可以自动生成客户端代码,充分体现了面向实体对象的远程调用的思想;Eventbus是异步的消息机制,基于cap的思想,不关心下游订阅方服务是否消费成功,保障了主服务业务的流畅性,同时也是一款分布式事务的实现方案,可以保障分布式架构中的数据的最终一致性。

我们今天主要介绍CAP在微服务中的实践案例。

搭建框架介绍

新建项目

  1. 新建解决方案 DotNetCore.Cap.Demo

  2. 新建项目 DotNetCore.Cap.Demo.Publisher 消息发布端

  3. 新建项目 DotNetCore.Cap.Demo.Subscriber 消息订阅端

主要sdk

  • 项目框架 netcoreapp 3.1

  • 消息队列选用RabbitMQ

  • 数据库存储选用PostgreSql

根据实际情况选择合适的消息队列和数据库存储

CAP 支持 Kafka、RabbitMQ、AzureServiceBus 消息队列:

PM> Install-Package DotNetCore.CAP.Kafka
PM> Install-Package DotNetCore.CAP.RabbitMQ
PM> Install-Package DotNetCore.CAP.AzureServiceBus

CAP 提供了 Sql Server, MySql, PostgreSQL,MongoDB 作为数据库存储:

PM> Install-Package DotNetCore.CAP.SqlServer
PM> Install-Package DotNetCore.CAP.MySql
PM> Install-Package DotNetCore.CAP.PostgreSql
PM> Install-Package DotNetCore.CAP.MongoDB

本次demo使用的nuget包如下所示

$ dotnet list package
项目“DotNetCore.Cap.Demo.Publisher”具有以下包引用[netcoreapp3.1]: 顶级包                                                          已请求      已解决   > DotNetCore.CAP                                             3.1.1    3.1.1> DotNetCore.CAP.PostgreSql                                  3.1.1    3.1.1> DotNetCore.CAP.RabbitMQ                                    3.1.1    3.1.1> Microsoft.VisualStudio.Azure.Containers.Tools.Targets      1.10.9   1.10.9> Npgsql.EntityFrameworkCore.PostgreSQL                      3.1.4    3.1.4> Npgsql.EntityFrameworkCore.PostgreSQL.Design               1.1.0    1.1.0项目“DotNetCore.Cap.Demo.Subscriber”具有以下包引用[netcoreapp3.1]:顶级包                                                          已请求      已解决> DotNetCore.CAP                                             3.1.1    3.1.1> DotNetCore.CAP.PostgreSql                                  3.1.1    3.1.1> DotNetCore.CAP.RabbitMQ                                    3.1.1    3.1.1> Microsoft.VisualStudio.Azure.Containers.Tools.Targets      1.10.9   1.10.9> Npgsql.EntityFrameworkCore.PostgreSQL                      3.1.4    3.1.4> Npgsql.EntityFrameworkCore.PostgreSQL.Design               1.1.0    1.1.0

DotNetCore.Cap.Demo.Publisher 消息发布端

修改Startup文件

注入dotnetcore.cap组件及数据库上下文

    services.AddDbContext<PgDbContext>(p => p.UseNpgsql("数据库连接字符串"));services.AddCap(x =>{//rabbitmq在docker运行时,需要映射两个端口:5672和15672//5672供程序集访问//15672供web访问//默认用户名和密码为:guest/guestx.UseRabbitMQ(p =>{p.HostName = "localhost";p.Port = 5672;p.UserName = "guest";p.Password = "guest";});x.UseEntityFramework<PgDbContext>();//x.FailedRetryCount = 1;//x.UseDashboard();});

新建Controller作为Publisher

  • 构造函数注入DotNetCore.CAP.ICapPublisher

提供了同步和异步的消息发布方法

  • 发布字符串消息

await _capPublisher.PublishAsync("消息名称", "消息内容");

        [HttpGet("string")]public async Task<IActionResult> PublishString(){await _capPublisher.PublishAsync("sample.rabbitmq.demo.string", "this is text!");return Ok();}
  • 发布对象

await _capPublisher.PublishAsync("消息名称", "消息对象");

        [HttpGet("dynamic")]public async Task<IActionResult> PublishDynamic(){await _capPublisher.PublishAsync("sample.rabbitmq.demo.dynamic", new{Name = "xiao gou",Age = 18});return Ok();}
  • 分布式事务场景

当需要在数据库操作后,发布消息出去,DotNetCore.Cap也提供了分布式事务的解决方案。它扩展的transcation能保证只有在数据库操作和消息发送都完成后,才提交Commit

        [HttpGet("transcation")]public async Task<IActionResult> PublishWithTranscation(){using (var trans = _pgDbContext.Database.BeginTransaction(_capPublisher)){var apiConfig = new ApiConfig{ApiName = "111122",ApiDesc = "223",ReturnType = "1",ReturnExpect = "1",IsAsync = true,OperCode = "999",OperTime = DateTime.Now};await _pgDbContext.ApiConfig.AddAsync(apiConfig);await _pgDbContext.SaveChangesAsync();_capPublisher.Publish("sample.rabbitmq.demo.transcation", apiConfig);trans.Commit();return Ok();}}

DotNetCore.Cap.Demo.Subscriber 消息订阅端

修改Startup文件

注入dotnetcore.cap组件及数据库上下文

    services.AddDbContext<PgDbContext>(p => p.UseNpgsql("数据库连接字符串"));services.AddCap(x =>{//rabbitmq在docker运行时,需要映射两个端口:5672和15672//5672供程序集访问//15672供web访问//默认用户名和密码为:guest/guestx.UseRabbitMQ(p =>{p.HostName = "localhost";p.Port = 5672;p.UserName = "guest";p.Password = "guest";});x.UseEntityFramework<PgDbContext>();//x.FailedRetryCount = 1;//x.UseDashboard();});

新建Controller作为Subscriber

  • 订阅字符串消息

[NonAction] 标签:Indicates that a controller method is not an action method.

[CapSubscribe] 标签:标志此方法为订阅方法,并以消息名称匹配发布端的消息事件

        [NonAction][CapSubscribe("sample.rabbitmq.demo.string")]public void SubscriberString(string text){Console.WriteLine($"【SubscriberString】Subscriber invoked, Info: {text}");}
  • 订阅对象消息

方法入参person即为消息体

        [NonAction][CapSubscribe("sample.rabbitmq.demo.dynamic")]public void SubscriberDynamic(dynamic person){Console.WriteLine($"【SubscriberDynamic】Subscriber invoked, Info: {person.Name} {person.Age}");}

新建Service作为Subscriber

  • 除了Controller可以作为消息订阅端外,也可以用继承自DotNetCore.CAP.ICapSubscribe接口的Service作为订阅端

  • Controller作为订阅者时,不用继承ICapSubscribe;Service作为订阅者时,必须继承ICapSubscribe

  • Controller和Service同时订阅了一个消息时,只触发了Service的消费;若要多个消费,需要在不同的Group下

using DotNetCore.CAP;
using System;namespace DotNetCore.Cap.Demo.Subscriber.Services
{/// <summary>/// 消费订阅服务/// </summary>public class SubscriberService : ICapSubscribe{[CapSubscribe("sample.rabbitmq.demo.string")]public void SubscriberString(string text){Console.WriteLine($"【SubscriberString】Subscriber invoked, Info: {text}");}[CapSubscribe("sample.rabbitmq.demo.dynamic")]public void SubscriberDynamic(dynamic person){Console.WriteLine($"【SubscriberDynamic】Subscriber invoked, Info: {person.Name} {person.Age}");}[CapSubscribe("sample.rabbitmq.demo.object")]public void SubscriberObject(Person person){Console.WriteLine($"【SubscriberObject】Subscriber invoked, Info: {person.Name} {person.Age}");}[CapSubscribe("sample.rabbitmq.demo.trans")]public void SubscriberTrans(ApiConfig apiConfig){Console.WriteLine($"【SubscriberTrans】Subscriber invoked, Info: {apiConfig.Id}");}}
}

总结

  • DotNetCore.Cap 是一种异步消息的通信,可以作为微服务间通信的一种方式

  • DotNetCore.Cap 为微服务架构提供了分布式事务的解决方案,保障了数据的最终一致性

  • 开发中,应根据实际业务需求和场景,选择合适可靠的微服务间通信方案

参考

https://github.com/dotnetcore/CAP/blob/master/README.md
https://book.douban.com/subject/33425123/

Demo 代码

https://github.com/cailin0630/DotNetCore.Cap.Demo

原文地址:https://www.cnblogs.com/jiangyihz/p/13864245.html

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

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

相关文章

软件构造学习笔记-第二周

本周课程把第六章测试的内容提前讲了一部分&#xff0c;主要为实验1服务&#xff0c;讲了有关测试的概念、作用和基本方法。“测试优先”的思想是非常重要的&#xff0c;根据spec写出简单而全面的测试&#xff0c;在方法/类完成后第一时间对其进行测试&#xff0c;保证每个方法…

T-SQL | 你需要了解的执行计划

【T-SQL】| 作者 / Edison Zhou这是EdisonTalk的第297篇学习分享T-SQL是ANSI和ISO SQL标准的MS SQL扩展&#xff0c;其正式名称为Transact-SQL&#xff0c;但一般程序员都称其为T-SQL。本文是我学习《T-SQL查询》一书的读书笔记&#xff0c;为你讲解执行计划是个什么鬼。1关于执…

软件构造学习笔记-实验1

记录一下做实验1时遇到的问题。 准备工作 1.GitHub的注册和配置 由于之前没有接触过GitHub&#xff0c;所以碰到了一些问题。GitHub是什么&#xff1f;怎么建立GitHub远程仓库与本地仓库的连接&#xff1f;怎么在GitHub上传和下载文件&#xff1f; 实验完成后我可以简单回答上…

好的自我介绍,面试成功一大半

大家好&#xff0c;我是Z哥。关于面试时的自我介绍&#xff0c;我想大家遇到的情况都差不多&#xff0c;大部分面试的第一个环节基本都是这个。每个人也都知道留下好的第一印象很重要&#xff0c;但我估计很多人对这件事的解决方式&#xff0c;也就在网上找个自我介绍的模版就完…

软件构造学习笔记-第三周

本周介绍了软件开发的几种模型&#xff0c;并重点介绍了Git。Git是分布式版本控制系统&#xff0c;可以通过SSH key建立远程与本地的连接&#xff0c;通过Git Bash中的命令进行文件的上传和下载。对于这门课程&#xff0c;Git的主要作用就是向TA提交实验代码。 软件开发生命周…

log4net直切ElasticSearch,小步快跑首选

很多小步快跑的公司&#xff0c;开发人员可能就3-4个&#xff0c;面对巨大业务压力&#xff0c;日连夜的赶着上线&#xff0c;快速试错&#xff0c;自然就没时间搭建一些基础设施&#xff0c;比如说logCenter&#xff0c;但初期项目不稳定&#xff0c;bug又多&#xff0c;每次都…

软件构造学习笔记-第四周

本周重点介绍了mutable和immutable的概念&#xff0c;有些抽象。对于immutable的数据类型来说&#xff0c;想修改其引用指向的值&#xff0c;必须使其指向新的内存区域&#xff0c;而不能在原有的内存区域做修改。mutable数据类型相反&#xff0c;可以在原来指向的内存区域进行…

壹佰文章总结| 关于ASP.NETCore的分享之路

公众号不让放外网链接&#xff0c;点击【阅读原文】&#xff0c;去我的博客园&#xff0c;可以看对应的详细文章。&#xff08;关于学习ASP.NET Core需要了解和掌握的知识点图&#xff09;一言不合就来图&#xff0c;各位博客园小伙伴大家好&#xff0c;感觉好久没有写文章了&a…

软件构造学习笔记-第五周

本周讲了AF、RI、Safety from rep exposure、spec等概念。这些是辅助程序设计的重要部分&#xff0c;需要在代码中以注释的形式体现&#xff0c;可以显著提高代码可读性&#xff0c;明确设计的目的。必须要养成写的习惯&#xff01;&#xff01;&#xff01; 设计规约 1.规约…

EFCore之SQL扩展组件BeetleX.EFCore.Extension

EFCore是.NETCore团队开发的一个ORM组件&#xff0c;但这个组件在执行传统SQL的时候并不方便&#xff0c;因此BeetleX.EFCore.Extension的设计目的是让EFCore执行传统SQL更简单方便。引用在使用组件之前需要引用它&#xff0c;可以通过以下地址获取最新版本https://www.nuget.o…

软件构造学习笔记-第六周

这周的重点是重载和重写。重载要求两方法的签名必须不同&#xff0c;而重写则要求两方法的签名必须相同。重载可以发生在同一个类中&#xff0c;也可以发生在父类和子类中&#xff1b;重写必须发生在父类和子类中。接口/抽象类不具有构造方法&#xff0c;只有将内部的抽象方法全…

云原生时代,.NET5必将称王!

“ 随着互联网持续高歌猛进&#xff0c;相关技术名词也是层出不穷。微服务、容器化、DevOps、ServerLess、FaaS&#xff0c;这两年最火的&#xff0c;当属云原生Cloud Native&#xff01;当下大部分企业还在追逐微服务架构落地&#xff0c;而下一代的架构云原生已如火如荼。程序…

软件构造学习笔记-实验2

P1 1.设计目标 首先对图的ADT进行两种实现&#xff08;从边和顶点出发&#xff09;&#xff0c;然后选择一种实现的ADT&#xff0c;根据输入的文件构建语料库&#xff0c;再利用构建的语料库&#xff0c;对输入字符串进行插入操作&#xff0c;并返回修改后的字符串。 2.有关AF…

海棠读社小程序研发(.Net Core版)

今天这篇博文是介绍海棠读社小程序开发的技术博文&#xff0c;由于博主是技术出身&#xff0c;开发过小程序和公众号&#xff0c;所以从决定做海棠读社开始就写代码了。因为只有技术和文化相结合&#xff0c;更能使传统文化大放异彩&#xff0c;更好地传播、讲好中国故事。漓江…

软件构造学习笔记-第七周

本周只有一节课&#xff0c;内容较少。对于不可变类型的相等比较&#xff0c;需要重写equals和hashCode方法&#xff0c;实现观察等价性。对于可变类型&#xff0c;不建议重写以上两方法&#xff0c;按照默认比较方式&#xff08;比较内存地址&#xff09;即可。 可变类型的相…

asp.net core监控—引入Prometheus(五)

上一篇博文中说到Prometheus有四种指标类型&#xff1a;Counter&#xff08;计数器&#xff09;、Gauge&#xff08;仪表盘&#xff09;、Histogram&#xff08;直方图&#xff09;、Summary&#xff08;摘要&#xff09;&#xff0c;并且我们做了一个Counter的Demo&#xff0c…

软件构造学习笔记-第八周

本周重点是Liskov可替换原则。它要求父类和子类的行为一致性&#xff0c;子类要有更强的不变量、更弱的前置条件、更强的后置条件。在该原则的要求下&#xff0c;每个子类都可以对父类进行替换。这在开发过程中会带来极大的便利&#xff0c;在实验3中学习并运用该原则。 有关复…

C# 中的只读结构体(readonly struct)

翻译自 John Demetriou 2018年4月8日 的文章 《C# 7.2 – Let’s Talk About Readonly Structs》[1]在本文中&#xff0c;我们来聊一聊从 C# 7.2 开始出现的一个特性 readonly struct。任一结构体都可以有公共属性、私有属性访问器等等。我们从以下结构体示例来开始讨论&#x…

软件构造学习笔记-第九周、第十周

因为本周五开始五一假期&#xff0c;所以只有一节软件构造课。因为内容还属于创建模式、结构模式、行为模式。将该堂课的内容整合到本博客中。本周的重点是程序开发模式&#xff0c;在写代码之前首先充分考虑采用哪种模式更有利于开发、维护。采用合适的设计模式帮助理清思路&a…

回顾 | 使用Visual Studio Code进行端到端应用程序开发

点击蓝字关注我们&#xff0c;获得更多课程吧~微软Reactor 为帮助广开发者&#xff0c;技术爱好者&#xff0c;更好的学习 Python&#xff0c;数据科学&#xff0c;机器学习&#xff0c;AI&#xff0c;区块链等技术&#xff0c;将每周三到周六&#xff0c;组织 3~5 场线上分享活…