【分布式事务】二、NET8分布式事务实践: DotNetCore.CAP 框架 、 消息队列(RabbitMQ)、 多类型数据库(MySql、MongoDB)

介绍

DotNetCore.CAP简称CAP, [CAP]是一个用来解决微服务或者分布式系统中分布式事务问题的一个开源项目解决方案,
同样可以用来作为 EventBus 使用,CAP 拥有自己的特色,它不要求使用者发送消息或者处理消息的时候实现或者继承任何接口,拥有非常高的灵活性。我们一直坚信约定大于配置,所以CAP使用起来非常简单,对于新手非常友好,并且拥有轻量级。

CAP 采用模块化设计,具有高度的可扩展性。你有许多选项可以选择,包括消息队列,存储,序列化方式等,系统的许多元素内容可以替换为自定义实现。

  1. github地址:https://github.com/dotnetcore/CAP
  2. 官网地址: https://cap.dotnetcore.xyz/
  3. 官网文档:https://cap.dotnetcore.xyz/user-guide/zh/getting-started/quick-start/

eShopOnContainer选择

环境准备

  1. 安装 MySql 参考: 七、阿里云 Linux CentOs7安装MySql
  2. 安装Docker 参考:六、Docker安装
  3. Docker 安装配置 MongDB 集群 参考:十、Linux Docker 安装配置 MongoDB集群
  4. Docker 安装 RabbitMQ 参考: 九、Linux Docker 安装 RabbitMQ

本项目源码地址:分布式事务架构 DotNetCore.CAP

一、NET8 集成 DotNetCore.CAP

1、新建分布式项目

Nuget引用

DotNetCore.CAP
DotNetCore.CAP.Dashboard #consul监听

CAP提供了Kafka、RabbitMQ消息队列

DotNetCore.CAP.Kafka
DotNetCore.CAP.RabbitMQ

CAP提供了SqlServer、MySql、PostgreSql、MongoDB 的扩展作为数据库存储

DotNetCore.CAP.SqlServer
DotNetCore.CAP.MySql
DotNetCore.CAP.PostgreSql
DotNetCore.CAP.MongoDB

我是在以前的 Abp.Vnext 项目上做的,其它框架其实也差不多,项目结构如下图:

在这里插入图片描述

2、用户服务(LAbpVnext.WebApi)

连接 127.0.0.1 userdb MySql数据库

(1)、UsersController.cs 代码

using DotNetCore.CAP;
using LAbpVnext.Application;
using Microsoft.AspNetCore.Mvc;namespace LAbpVnext.WebApi.Controllers
{[ApiController][Route("[controller]")]public class UsersController : ControllerBase{private static string _publishName = "RabbitMQ.MySql.OrderService";private readonly ICapPublisher _iCapPublisher;private readonly ILogger<UsersController> _logger;private readonly IUserAppService _userAppService;public UsersController(ICapPublisher capPublisher, ILogger<UsersController> logger, IUserAppService userAppService){_iCapPublisher = capPublisher;_logger = logger;_userAppService = userAppService;}[HttpGet("Login")]public ActionResult Login(){return Ok();}/// <summary>/// 获取所有用户/// </summary>/// <returns></returns>[HttpGet("GetAll")]public async Task<List<UserDto>> GetAll() {var users = await _userAppService.GetAll();return users;}/// <summary>/// 事务测试/// </summary>/// <returns></returns>[HttpGet("TestTransaction")]public async Task<UserDto> TestTransaction(){var user = await _userAppService.GetById(1);Console.WriteLine($"【用户】发布任务成功!{DateTime.Now.ToString()}");await _iCapPublisher.PublishAsync(_publishName, user);return user;}}
}

(2)、LAbpVnextUserApiModule.cs 代码

  using DotNetCore.CAP.Messages;
using LAbpVnext.Application;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
using DotNetCore.CAP.Dashboard.NodeDiscovery;namespace LAbpVnext.WebApi
{[DependsOn(typeof(AbpAspNetCoreMvcModule),typeof(AbpAutofacModule),typeof(LAbpVnextApplicationModule))]public class LAbpVnextUserApiModule : AbpModule{/// <summary>/// 依赖注入容器/// </summary>/// <param name="context"></param>public override void ConfigureServices(ServiceConfigurationContext context){var basePath = AppContext.BaseDirectory;var configuration = context.Services.GetConfiguration();//引入配置文件var _config = new ConfigurationBuilder().SetBasePath(basePath).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();// Add services to the container.context.Services.AddControllers();#region 添加 CAPcontext.Services.AddCap(x =>{x.UseMySql(_config.GetConnectionString("Default"));//指定CAP的发布数据库地址x.UseRabbitMQ(c => { c.HostName = _config["RabbitMQ:Host"];c.UserName = _config["RabbitMQ:User"];c.Password = _config["RabbitMQ:Pwd"];});//x.FailedRetryCount = 10;//x.FailedRetryInterval = 60;//x.FailedThresholdCallback = failed => {Console.WriteLine($"MessageType {failed.MessageType} 失败了, 重试了 {x.FailedRetryCount} 次, 消息名称: {failed.Message.GetName()}");};#region 注册Consul可视化//旧:DiscoveryOptions;新:ConsulDiscoveryOptions//DiscoveryOptions discoveryOptions = new DiscoveryOptions();//this.Configuration.Bind(discoveryOptions);//x.UseDashboard();//ConsulDiscoveryOptions discoveryOptions = new ConsulDiscoveryOptions();//configuration.Bind(discoveryOptions);//x.UseConsulDiscovery(d =>//{//    d.DiscoveryServerHostName = discoveryOptions.DiscoveryServerHostName;//    d.DiscoveryServerPort = discoveryOptions.DiscoveryServerPort;//    d.CurrentNodeHostName = discoveryOptions.CurrentNodeHostName;//    d.CurrentNodePort = discoveryOptions.CurrentNodePort;//    d.NodeId = discoveryOptions.NodeId;//    d.NodeName = discoveryOptions.NodeName;//    d.MatchPath = discoveryOptions.MatchPath;//});#endregion});#endregion#region 添加swagger注释context.Services.AddSwaggerGen(c =>{c.SwaggerDoc("v1", new OpenApiInfo{Version = "v1",Title = "LAbpVnext.UserApi"});var xmlPath = Path.Combine(basePath, "LAbpVnext.UserApi.xml");c.IncludeXmlComments(xmlPath, true);//var xmlDomainPath = Path.Combine(basePath, "HuaWeiServer.Domain.xml");//c.IncludeXmlComments(xmlDomainPath, true);c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme{Description = "Value: Bearer {token}",Name = "Authorization",In = ParameterLocation.Header,Type = SecuritySchemeType.ApiKey,Scheme = "Bearer"});c.AddSecurityRequirement(new OpenApiSecurityRequirement(){{new OpenApiSecurityScheme{Reference = new OpenApiReference{Type = ReferenceType.SecurityScheme,Id = "Bearer"},Scheme = "oauth2",Name = "Bearer",In = ParameterLocation.Header,},

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

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

相关文章

利用pythonstudio写的PDF、图片批量水印生成器,可同时为不同读者生成多组水印

现在很多场合需要将PDF或图片加水印&#xff0c;本程序利用pythonstudio编写。 第一步 界面 其中&#xff1a; LstMask:列表框 PopupMenu:PmnMark LstFiles:列表框 PopupMenu:PmnFiles OdFiles:文件选择器 Filter:PDF文件(.PDF)|.PDF|图像文件(.JPG)|.JPG|图像文件(.png…

面试:TCP、UDP如何解决丢包问题

文章目录 一、TCP丢包原因、解决办法1.1 TCP为什么会丢包1.2 TCP传输协议如何解决丢包问题1.3 其他丢包情况&#xff08;拓展&#xff09;1.4 补充1.4.1 TCP端口号1.4.2 多个TCP请求的逻辑1.4.3 处理大量TCP连接请求的方法1.4.4 总结 二、UDP丢包2.1 UDP协议2.1.1 UDP简介2.1.2…

Python的函数(补充浅拷贝和深拷贝)

一、定义 函数的定义&#xff1a;实现【特定功能】的代码块。 形参&#xff1a;函数定义时的参数&#xff0c;没有实际意义 实参&#xff1a;函数调用/使用时的参数&#xff0c;有实际意义 函数的作用&#xff1a; 简化代码提高代码重用性便于维护和修改提高代码的可扩展性…

Spring Boot框架的知识分类技术解析

2 开发技术 2.1 VUE框架 Vue.js&#xff08;读音 /vjuː/, 类似于 view&#xff09; 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 2.2 Mysql数据库 …

Hive详解

1 Hive基本概念 Hive是一个构建在Hadoop上的数据仓库框架。最初&#xff0c;Hive是由Facebook开发&#xff0c;后来移交由Apache软件基金会开发&#xff0c;并作为一个Apache开源项目。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据…

llamaIndex和langchain对比及优劣对比

一. LangChain vs LlamaIndex: 基本描述 LlamaIndex在搜索和检索任务方面表现出色。它是一个强大的数据索引和查询工具&#xff0c;非常适合需要高级搜索的项目。LlamaIndex能够处理大型数据集&#xff0c;从而实现快速准确的信息检索。 LangChain是一个模块化和灵活的工具集框…

《重学Java设计模式》之 工厂方法模式

《重学Java设计模式》之 建造者模式 《重学Java设计模式》之 原型模式 《重学Java设计模式》之 单例模式 模拟发奖多种商品 工程结构 奖品发放接口 package com.yys.mes.design.factory.store;public interface ICommodity {/*** Author Sherry* Date 14:20 2024/11/6**/voi…

【C++笔记】string类的模拟实现

前言 各位读者朋友们大家好&#xff01;上期我们讲解了string类的基础用法&#xff0c;这期我们来模拟实现一下string类。 目录 前言一. string类的构造函数1. 1 无参构造2.2 带参构造1.3 无参和带参构造结合1.4 拷贝构造1.5 c_str 二. string类的析构函数三. 字符串的遍历3.…

java中ArrayList的使用存储对象的易错点

ArrayList存储对象的易错点 上面这种写法是有逻辑问题的&#xff0c;因为只创建了一个Student对象&#xff0c;因此最后打印出来的结果是三个最后赋值的结果。 下面我们来形象看下存储关系 集合中存储的始终是第一个对象的地址&#xff0c;而每次输入新的名字和年龄&#xf…

栈和队列(Java)

一.栈&#xff08;Stack&#xff09; 1.定义 栈是限定仅在表尾进行插入或删除操作的线性表 一般的表尾称为栈顶 表头称为栈底 栈具有“后进先出”的特点 2.对栈的模拟 栈主要具有以下功能&#xff1a; push(Object item)&#xff1a;将元素item压入栈顶。 pop()&am…

Angular 和 Vue2.0 对比

前言 &#xff1a;“业精于勤&#xff0c;荒于嬉&#xff1b;行成于思&#xff0c;毁于随” 很久没写博客了&#xff0c;大多记录少进一步探查。 Angular 和 Vue2.0 对比&#xff1a; 一.概念 1.1 Angular 框架&#xff1a; 是一款由谷歌开发的开源web前端框架&#xff08;核…

基于Multisim数字电子秒表0-60S电路(含仿真和报告)

【全套资料.zip】数字电子秒表电路Multisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 1.秒表最大计时值为60秒&#xff1b; 2. 2位数码管显示&#xff0c;分辨率为1秒&#xff1b; 3.具有清零…

安卓智能指针sp、wp、RefBase浅析

目录 前言一、RefBase1.1 引用计数机制1.2 设计目的1.3 主要方法1.4 如何使用1.5 小结 二、sp和wp2.1 引用计数机制2.2 设计目的2.3 主要方法2.3.1 sp2.3.2 wp 2.4 如何使用2.5 小结 四、参考链接 前言 安卓底层binder中&#xff0c;为什么 IInterface要继承自RefBase &#x…

【论文笔记】Prefix-Tuning: Optimizing Continuous Prompts for Generation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Prefix-Tuning: Optimizin…

【Web前端】从回调到现代Promise与Async/Await

异步编程是一种让程序能够在等待某些操作完成的同时继续执行其他任务的关键技术&#xff0c;打破了传统编程中顺序执行代码的束缚。这种编程范式允许开发者构建出能够即时响应用户操作、高效处理网络请求和资源加载的应用程序。通过异步编程&#xff0c;JavaScript 能够在执行耗…

【CSS】“flex: 1“有什么用?

flex 属性的组成 flex 属性是一个复合属性&#xff0c;包含以下三个子属性&#xff1a; flex-grow&#xff1a;决定元素在容器中剩余空间的分配比例。默认值为 0&#xff0c;表示元素不会扩展。当设置为正数时&#xff0c;元素会按照设定比例扩展。flex-shrink&#xff1a;决…

计算机课程管理:Spring Boot与工程认证的协同创新

3系统分析 3.1可行性分析 通过对本基于工程教育认证的计算机课程管理平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于工程教育认证的计算机课程管理平…

【SpringBoot】18 上传文件到数据库(Thymeleaf + MySQL)

Git仓库 https://gitee.com/Lin_DH/system 介绍 使用 Thymeleaf 写的页面&#xff0c;将&#xff08;txt、jpg、png&#xff09;格式文件上传到 MySQL 数据库中。 依赖 pom.xml <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --><depende…

Sharding运行模式、元数据、持久化详解

运行模式 单机模式 能够将数据源和规则等元数据信息持久化&#xff0c;但无法将元数据同步至多个Sharding实例&#xff0c;无法在集群环境中相互感知。 通过某一实例更新元数据之后&#xff0c;会导致其他实例由于获取不到最新的元数据而产生不一致的错误。 适用于工程师在本…

挖掘web程序中的OAuth漏洞:利用redirect_uri和state参数接管账户

本文探讨了攻击者如何利用OAuth漏洞&#xff0c;重点是滥用redirect_uri和state参数以接管用户账户。如果redirect_uri参数验证不严&#xff0c;可能会导致未经授权的重定向到恶意服务器&#xff0c;从而使攻击者能够捕获敏感信息。同样&#xff0c;state参数的错误实现可能使O…