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

news2024/11/24 2:29:10

介绍

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 添加 CAP
            context.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.coloradmin.cn/o/2238973.html

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

相关文章

vue3项目中内嵌vuepress工程两种实现方式

目录 一、示例二、创建vuepress工程三、配置vue项目的打包命令四、 通过iframe嵌套实现过程五、 将vue项目打包&#xff0c;启本地服务运行index.html 一、示例 vue项目&#xff0c;点击用户手册按钮&#xff0c;通过a标签跳转到vuepress框架搭建的页面。点击后者通过路由跳转…

智能座舱多屏项目,中控屏切换语言,后排屏闪黑屏问题

1. 背景 智能座舱多屏项目&#xff0c;中控屏切换语言&#xff0c;后排屏闪黑屏问题 2. 详细分析过程 通过events log查看activity的生命周期&#xff1a;adb shell logcat -b events com.android.rwhvac.view.behind.BehindActivity2 : displayId 2 副屏app com.android.…

多商户中英双语电商系统设计与开发 PHP+mysql

随着全球电商市场的扩展&#xff0c;多商户平台成为了越来越多商家参与全球贸易的重要方式。为了适应不同语言用户的需求&#xff0c;尤其是中英双语用户的需求&#xff0c;设计一个支持中英双语的电商系统显得尤为重要。本文将重点探讨如何设计一个多商户中英双语电商系统&…

Ansys Zemax | 手机镜头设计 - 第 4 部分:用LS-DYNA进行冲击性能分析

该系列文章将讨论智能手机镜头模组设计的挑战&#xff0c;从概念和设计到制造和结构变形分析。本文是四部分系列中的第四部分&#xff0c;它涵盖了相机镜头的显式动态模拟&#xff0c;以及对光学性能的影响。使用Ansys Mechanical和LS-DYNA对相机在地板上的一系列冲击和弹跳过程…

【JavaEE初阶】多线程上部

文章目录 本篇目标&#xff1a;一、认识线程&#xff08;Thread&#xff09;1.概念&#xff1a;2.创建线程 二、Thread 类及常见方法2.1 Thread 的常见构造方法2.2 Thread 的几个常见属性2.3 启动⼀个线程 - start()2.4 中断⼀个线程2.5 等待⼀个线程 - join()2.6 获取当前线程…

丹摩征文活动|智谱AI引领是实现文本可视化 - CogVideoX-2b 部署与使用

文章目录 前言一、DAMODEL平台特性二、创建CPU云实例三、CogVedioX介绍四、DAMODEL一键部署CogVideoX1. 创建丹摩实例(参考上述介绍)2. 配置环境和依赖3. 模拟与配置文件4. 开始运行4.1 调试4.2 webUI4.3 端口映射 前言 DAMODEL&#xff08;丹摩智算&#xff09;是一款专为满足…

MySQL的知识巩固

目录 三大范式 第一范式: 第二范式: 第三范式: 巴斯-科德范式(BCNF): 反范式&#xff1a; MySQL的工作原理 三大范式 第一范式: 一个字段只表明一个事情 优点: 数据一致性&#xff1a; 在1NF中&#xff0c;由于每个属性都是原子的&#xff0c;因此避免了在一个属性中存…

越野车TV 1.0.5337 | TV端越野赛车游戏,解锁无限金币

越野车TV是一款专为电视设计的越野赛车游戏&#xff0c;最初是安卓手机端的游戏&#xff0c;现已移植到TV端并兼容遥控器操作。这款游戏的特点是解锁了VIP&#xff0c;所有资源都可以免费使用。游戏采用3D横版卡通风格&#xff0c;提供真实的越野赛车体验。玩家可以在崎岖的赛道…

MySQL 迁移 dm

参考链接 此处为语雀内容卡片&#xff0c;点击链接查看&#xff1a;MySQL 5.7.27 迁移 DM 8 语雀 迁移前准备 以下中的命名&#xff0c;密码都是可修改的&#xff0c;这里给出的就只是一个例子 创建表空间 # 创建表空间名为 dbTest&#xff0c;路径为 Z:\fei\data\dm\dbT…

信息安全工程师(82)操作系统安全概述

一、操作系统安全的概念 操作系统安全是指操作系统在基本功能的基础上增加了安全机制与措施&#xff0c;从而满足安全策略要求&#xff0c;具有相应的安全功能&#xff0c;并符合特定的安全标准。在一定约束条件下&#xff0c;操作系统安全能够抵御常见的网络安全威胁&#xff…

从0开始学习Linux——文件管理

往期目录&#xff1a; 从0开始学习Linux——简介&安装 从0开始学习Linux——搭建属于自己的Linux虚拟机 从0开始学习Linux——文本编辑器 从0开始学习Linux——Yum工具 从0开始学习Linux——远程连接工具 从0开始学习Linux——文件目录 从0开始学习Linux——网络配置 从0开…

vue中调用全屏方法、 elementUI弹框在全屏模式下不出现问题、多级嵌套弹框蒙层遮挡问题等处理与实现方案

全屏模式下弹框不展示的原因是elementUI的弹框我们让他挂在body中了&#xff0c;而我们全屏的div盒子不是整个文档&#xff0c;这时候就找不到弹框了。 当我们把弹框改为插入到父元素上 这时候会出现蒙层盖住整个页面&#xff0c;什么也点不了的问题。 这是elementUI官方的一个…

特征检测与特征匹配方法笔记+代码分享

在一幅图像中&#xff0c;总能发现其独特的像素点&#xff0c;这些点可以被视为该图像的特征&#xff0c;我们称之为特征点。在计算机视觉领域中&#xff0c;基于特征点的图像特征匹配是一项至关重要的任务&#xff0c;因此&#xff0c;如何定义并识别一幅图像中的特征点显得尤…

补: 力扣145 : 二叉树的后序遍历

天才的回归 ---- 二叉树的后序遍历 描述&#xff1a; **给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 ** 示例&#xff1a; 解法&#xff1a;递归就不说了&#xff0c;看下遍历法&#xff0c;与先序和中序略有不同 简单来说注意两个点&#xff1a; 1&…

Centos8 安装 JDK / Python / MySQL / Redis / Nginx

安装 JDK 华为镜像 JDK 下载地址&#xff1a;https://repo.huaweicloud.com:8443/artifactory/java-local/jdk/ 这里安装 JDK8 为例&#xff1a; # 这里直接通过 wget 下载 wget https://repo.huaweicloud.com:8443/artifactory/java-local/jdk/8u202-b08/jdk-8u202-linux-x…

使用轻易云平台高效集成聚水潭与南网订单数据

高效实现聚水潭与南网供应商对接的数据集成方案 普通发货对接南网供应商配送通知接口 在现代数据集成项目中&#xff0c;如何高效、可靠地实现不同系统之间的数据对接是一个关键挑战。本文将聚焦于一个实际案例&#xff1a;将聚水潭平台的数据集成到南方电网商城平台&#xff…

【经验分享】一招解决VMware虚拟机存储空间越来越大的问题

【经验分享】一招解决VMware虚拟机硬盘空间越来越大的问题 前言一、解决办法二、补充说明 前言 在使用虚拟机过程中&#xff0c;会出现用着用着虚拟机硬盘占用空间越来越大的问题。即使删除了文件&#xff0c;依然会占用宿主机的硬盘空间。如果虚拟机一开始分配的硬盘空间过大…

使用Element UI实现一个拖拽图片上传,并可以Ctrl + V获取图片实现文件上传

要在 Element UI 的拖拽上传组件中实现 Ctrl V 图片上传功能&#xff0c;可以通过监听键盘事件来捕获粘贴操作&#xff0c;并将粘贴的图片数据上传到服务器。 版本V1&#xff0c;实现获取粘贴板中的文件 注意&#xff0c;本案例需要再你已经安装了Element UI并在项目中正确配…

Ascend Extension for PyTorch是个what?

1 Ascend Extension for PyTorch Ascend Extension for PyTorch 插件是基于昇腾的深度学习适配框架&#xff0c;使昇腾NPU可以支持PyTorch框架&#xff0c;为PyTorch框架的使用者提供昇腾AI处理器的超强算力。 项目源码地址请参见Ascend/Pytorch。 昇腾为基于昇腾处理器和软…

strtok_s详解,实现使用strtok_s分割字符串,并返回包含分割符的子串

1.strtok_s函数原型 strtok_s 是一个线程安全的字符串分割函数&#xff0c;它是 strtok 的一个变体&#xff0c;用于将字符串分割成一系列的标记&#xff08;tokens&#xff09;。与 strtok 不同&#xff0c;strtok_s 需要一个额外的参数来保存上下文信息&#xff0c;这样它就…