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

介绍

[CAP]是一个用来解决微服务或者分布式系统中分布式事务问题的一个开源项目解决方案,
同样可以用来作为 EventBus 使用

  1. github地址:https://github.com/dotnetcore/CAP
  2. 官网地址: https://cap.dotnetcore.xyz/
  3. 官网文档:https://cap.dotnetcore.xyz/userguide/zh/cap/idempotence/

eShopOnContainer选择

环境准备

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

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 数据库

(1)、UsersController 代码

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 代码

  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,
                        },new List<string>()
                      }<

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

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

相关文章

【论文阅读】Learning dynamic alignment via meta-filter for few-shot learning

通过元滤波器学习动态对齐以实现小样本学习 引用&#xff1a;Xu C, Fu Y, Liu C, et al. Learning dynamic alignment via meta-filter for few-shot learning[C]//Proceedings of the IEEE/CVF conference on computer vision and pattern recognition. 2021: 5182-5191. 论文…

IDEA 2024使用mybatisplus插件生成代码在项目中

在IDEA 插件市场搜索“mybatisplus”插件并安装&#xff0c;安装好后重启IDEA&#xff0c;安装过程网上很多教程&#xff0c;这里略过&#xff1b;IDEA 2024配置数据库和生成代码迁移到了Tools菜单下&#xff0c;原先版本在Other; 先完成数据库配置&#xff0c;点击Config Data…

Android CCodec Codec2 (十九)C2LinearBlock

在上一篇文章的结尾&#xff0c;我们看到fetchLinearBlock方法最终创建了一个C2LinearBlock对象。这一节&#xff0c;我们将深入了解C2LinearBlock是什么&#xff0c;它的作用是什么&#xff0c;以及它是如何被创建的。 1、_C2BlockFactory 先对上一篇文章的结尾内容做简单回顾…

LabVIEW离心泵性能优化测试系统

开发了一套基于LabVIEW平台开发的离心泵性能优化测试系统。系统集成了数据采集、流量控制、数据存储、报表生成等功能&#xff0c;提供了低成本、便捷操作的解决方案&#xff0c;适用于工业场景中对离心泵性能的精确测评。 项目背景 随着工业化进程的加速&#xff0c;离心泵在…

【NLP自然语言处理】深入探索Self-Attention:自注意力机制详解

目录 &#x1f354; Self-attention的特点 &#x1f354; Self-attention中的归一化概述 &#x1f354; softmax的梯度变化 3.1 softmax函数的输入分布是如何影响输出的 3.2 softmax函数在反向传播的过程中是如何梯度求导的 3.3 softmax函数出现梯度消失现象的原因 &…

MML 中使用 libevent +std::async unix socket domain 进程间通信

可以执行大量超时的接口,直到任务执行完成 还可以在一个事件做检测&#xff0c;funtcure 中的值为ready 状态 uds 的用法和tcp 类似&#xff0c;会维护一个链接状态和分配一个链接套接字,这就为异步执行提供了很方便的条件 客户端就安静的做一个计时,看是否在固定事件内返回执行…

基础算法练习--滑动窗口(已完结)

算法介绍 滑动窗口算法来自tcp协议的一种特性,它的高效使得其也变成了算法题的一种重要考点.滑动窗口的实现实际上也是通过两个指针前后遍历集合实现,但是因为它有固定的解题格式,我将其单独做成一个篇章. 滑动窗口的解题格式: 首先,定义两个指针left和right,与双指针不同的…

算法:只出现一次的数字II

题目 链接&#xff1a;leetcode链接 思路分析 这道题目其实是一个观察题&#xff0c;比较考察观察能力。 数组中只有一个元素只出现一次&#xff0c;其他的元素都出现三次 我们假设有n个元素出现三次 那么所有的元素的第i位的和加起来只有下面的四种情况 3n * 0 0 3n * 0…

【rust】rust基础代码案例

文章目录 代码篇HelloWorld斐波那契数列计算表达式&#xff08;加减乘除&#xff09;web接口 优化篇target/目录占用一个g&#xff0c;仅仅一个actix的helloWorld demo升级rust版本&#xff0c; 通过rustupcargo换源windows下放弃吧&#xff0c;需要额外安装1g的toolchain并且要…

鸿蒙基本组件结构

组件结构 1. 认识基本的组件结构 ArkTS通过装饰器Component 和Entry 装饰 struct 关键字声明的数据结构&#xff0c;构成一个自定义组件 自定义组件中提供了一个build函数&#xff0c;开发者需要在函数内以链式调用的方式进行基本的UI描述&#xff0c;UI描述的方法请参考UI描述…

Python并发编程库:Asyncio的异步编程实战

Python并发编程库&#xff1a;Asyncio的异步编程实战 在现代应用中&#xff0c;并发和高效的I/O处理是影响系统性能的关键因素之一。Python的asyncio库是专为异步编程设计的模块&#xff0c;提供了一种更加高效、易读的并发编程方式&#xff0c;适用于处理大量的I/O密集型任务…

快速开发工具 Vite

快速开发工具 vite 摘要&#xff1a; **概念&#xff1a;**Vite 是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验 **构造&#xff1a;**Vite 主要由一个开发服务器和一套构建指令组成。 Vite底层的服务器转换和转发&#xff1a;以处理ts文件为例 1-读取 forma…

Servlet-Filter

文章目录 一. Filter 过滤器1. 概括2. 原理3. api配置过滤器(Filter)拦截路径1.xml 方式2.注解方式 4. 生命流程a.执行流程b.拦截路径c.过滤器链 5. 登录校验-Filter 一. Filter 过滤器 1. 概括 过滤器&#xff0c;顾名思义就是对事物进行过滤的&#xff0c;在 Web 中的过滤器…

Hadoop简介及单点伪分布式安装

目录 1. 大数据2. Hadoop简介3. Hadoop伪分布式安装4. Hadoop启动参考 1. 大数据 大数据的定义&#xff1a;一种规模大到在获取、存储、管理、分析方面大大超出传统数据库软件工具能力范围的数据集合。   特征&#xff1a;   1.海量的数据规模   2.快速的数据流转   3.…

python练习-袭击敌机

$ python -m pip install --user pygame1、画游戏框 class Settings:def __init__(self):self.screen_width 1200self.screen_height 800self.bg_color (230, 230, 230)import sys import pygame from settings import Settingsclass AlienInvasion:def __init__(self):pyg…

京东零售推荐系统可解释能力详解

作者&#xff1a;智能平台 张颖 本文导读 本文将介绍可解释能力在京东零售推荐系统中的应用实践。主要内容包括以下几大部分&#xff1a;推荐系统可解释定义、系统架构、排序可解释、模型可解释、流量可解释。 推荐系统可解释定义 推荐系统可解释的核心包括三部分&#xff0…

设备数据采集网关工作原理及优势-天拓四方

在日益智能化的时代&#xff0c;设备数据采集网关作为物联网系统中的关键组件&#xff0c;正扮演着越来越重要的角色。它不仅连接着各种设备&#xff0c;还负责数据的采集、处理与传输&#xff0c;为企业的数字化转型提供了坚实的基础。本文将详细探讨设备数据采集网关的定义、…

MLU运行SD3部署手册

文章目录 前言一、平台环境准备二、模型下载三、环境准备四.代码准备五.效果展示 前言 Stable Diffusion 3各版本模型在以下多个方面表现出色&#xff1a; 可定制性&#xff1a;轻松微调模型以满足特定创作需求&#xff0c;或根据定制的工作流程构建应用程序。 高效性能&#…

Webserver(3.3)生产者消费者模型

目录 生产者消费者简单模型条件变量信号变量 生产者消费者简单模型 //生产者消费者模型#include <stdio.h> #include<pthread.h> #include<stdlib.h> #include<unistd.h>struct Node{int num;struct Node * next; }; //头结点 struct Node * headNULL…

Obsidian之与Typora图片格式相互兼容

来源 [Obsidian之与Typora图片格式相互兼容 - 简书 (jianshu.com)](https://www.jianshu.com/p/303433fe82b9) 下载插件customer attachment location&#xff0c;并设置