net core cap结合redis+数据库实现最终一致性

CAP 同时支持使用 RabbitMQ,Kafka,Azure Service Bus 等进行底层之间的消息发送。
CAP 目前支持使用 Sql Server,MySql,PostgreSql,MongoDB 数据库的项目。
一般是cap+Kafka,这里使用cap+redis
安装DotNetCore.CAP nuGet包

配置 appsettings.json 数据 。
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"Mysql_Conn": "Server=localhost;port=3306;Database=db1;UserId=root;Password=123456",
},
"RabbitMQ": {
"HostName": "192.168.122.199",
"UserName": "admin",
"Password": "123456",
"VirtualHost": "vhost_lihy",
"Port": 5672,
"ExchangeName": "cap.text.lihy.exchange"
},
"AllowedHosts": "*"
}
根据底层消息队列,你可以选择引入不同的包:
PM> Install-Package DotNetCore.CAP.Kafka
PM> Install-Package DotNetCore.CAP.RabbitMQ
PM> Install-Package DotNetCore.CAP.AzureServiceBus
CAP 目前支持使用 SQL Server, PostgreSql, MySql, 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 //需要 MongoDB 4.0+ 集群
在 Startup.cs 文件中,添加如下配置:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<CapDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("Mysql_Conn"))); services.AddCap(x =>
{
//如果你使用的 EF 进行数据操作,你需要添加如下配置:
x.UseEntityFramework<CapDbContext>(); //可选项,你不需要再次配置 x.UseSqlServer 了 //如果你使用的ADO.NET,根据数据库选择进行配置:
//x.UseSqlServer("数据库连接字符串");
//x.UseMySql("server=localhost;port=3306;userid=root;password=123456;database=db1;SslMode=none");
//x.UsePostgreSql("数据库连接字符串"); //如果你使用的 MongoDB,你可以添加如下配置:
//x.UseMongoDB("ConnectionStrings"); //注意,仅支持MongoDB 4.0+集群 //CAP支持 RabbitMQ、Kafka、AzureServiceBus 等作为MQ,根据使用选择配置:
x.UseRabbitMQ(o =>
{
o.HostName = Configuration.GetSection("RabbitMQ")["HostName"];
o.UserName = Configuration.GetSection("RabbitMQ")["UserName"];
o.Password = Configuration.GetSection("RabbitMQ")["Password"];
o.VirtualHost = Configuration.GetSection("RabbitMQ")["VirtualHost"];
o.Port = Convert.ToInt32(Configuration.GetSection("RabbitMQ")["Port"]);
//指定Topic exchange名称,不指定的话会用默认的
o.ExchangeName = Configuration.GetSection("RabbitMQ")["ExchangeName"]; }); //设置处理成功的数据在数据库中保存的时间(秒),为保证系统新能,数据会定期清理。
x.SucceedMessageExpiredAfter = 24 * 3600; //设置失败重试次数
x.FailedRetryCount = 5; //x.UseKafka("ConnectionStrings");
//x.UseAzureServiceBus("ConnectionStrings"); x.UseDashboard();
}); }
发布事件/消息
新建 PublishController 控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc;
using MySql.Data.MySqlClient; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace NETCORE.CAP.Controllers
{
[Route("api/[controller]")]
public class PublishController : Controller
{ private readonly ICapPublisher _capBus; public PublishController(ICapPublisher capPublisher)
{
_capBus = capPublisher;
} /// <summary>
/// 不使用事务
/// </summary>
/// <returns></returns>
[Route("~/without/transaction")]
public IActionResult WithoutTransaction()
{
_capBus.Publish("xxx.services.show.time", DateTime.Now); return Ok();
} ////Ado.Net 中使用事务,自动提交
//[Route("~/adonet/transaction")]
//public IActionResult AdonetWithTransaction()
//{
// using (var connection = new MySqlConnection(ConnectionString))
// {
// using (var transaction = connection.BeginTransaction(_capBus, autoCommit: true))
// {
// //业务代码 // _capBus.Publish("xxx.services.show.time", DateTime.Now);
// }
// }
// return Ok();
//} ////EntityFramework 中使用事务,自动提交
//[Route("~/ef/transaction")]
//public IActionResult EntityFrameworkWithTransaction([FromServices]AppDbContext dbContext)
//{
// using (var trans = dbContext.Database.BeginTransaction(_capBus, autoCommit: true))
// {
// //业务代码 // _capBus.Publish("xxx.services.show.time", DateTime.Now);
// }
// return Ok();
//} }
}
订阅事件/消息
新建 ReceivedController 控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace NETCORE.CAP.Controllers
{
[Route("api/[controller]")]
public class ReceivedController : Controller
{
[NonAction]
[CapSubscribe("xxx.services.show.time")]
public void CheckReceivedMessage(DateTime time)
{
Console.WriteLine(time);
//return Task.CompletedTask;
}
}
}
运行后,
数据库即生成两张表

调用接口 https://localhost:5001/without/transaction
在数据表中可查看相关状态。
Cap 仪表盘
默认地址 https://localhost:5001/cap

Dashboard介绍
capOptions.UseDashboard(dashoptions =>
{
dashoptions.AppPath = "applicationpath";
dashoptions.PathMatch = "/cap";
dashoptions.Authorization = new[] { new CapDashboardFilter() }; });
这里只说这几个参数
AppPath:应用程序路径 访问dashboard的时候会有一个返回应用的操作,这个即是应用的地址
PathMatch:不设置的情况下都是cap,可以指定自己的dashboard路由地址
Authorization:授权处理
授权处理具体实现
只需要实现接口IDashboardAuthorizationFilter即可
public class CapDashboardFilter : IDashboardAuthorizationFilter
{ public bool Authorize(DashboardContext context)
{
return true;
}
}
通过DashboardContext上下文处理请求,允许返回true,不允许返回false
附代码:https://gitee.com/wuxincaicai/NETCORE.git
net core cap结合redis+数据库实现最终一致性的更多相关文章
- 脑裂 CAP PAXOS 单元化 网络分区 最终一致性 BASE
阿里技术专家甘盘:浅谈双十一背后的支付宝LDC架构和其CAP分析 https://mp.weixin.qq.com/s/Cnzz5riMc9RH19zdjToyDg 汤波(甘盘) 技术琐话 2020- ...
- C#.Net Core 操作Docker中的redis数据库
做软件开发的人,会在本机安装很多开发时要用到的软件,比如数据库,有MS SQL Server,MySQL,等,如果每种数据库都按照在本机确实有点乱,这个时候我们就想用虚拟机来隔离,这样就不会扰乱本机一 ...
- 【Redis数据库】再有人问你CAP理论是什么,就把这篇文章发给他
CAP是Consistency(一致性),Availability(可用性),Partition tolerance(分区容错性)的缩写.在学习redis过程中看到这个名词,查找各位大佬的文章发现这篇 ...
- 分布式事务最终一致性-CAP框架轻松搞定
前言 对于分布式事务,常用的解决方案根据一致性的程度可以进行如下划分: 强一致性(2PC.3PC):数据库层面的实现,通过锁定资源,牺牲可用性,保证数据的强一致性,效率相对比较低. 弱一致性(TCC) ...
- NoSql的三大基石:CAP理论&BASE&最终一致性
关系型数据库的局限 NoSql出现在关系型数据库之后,主要是为了解决关系型数据库的短板,我们先来看看随着软件行业的发展,关系型数据库面临了哪些挑战: 1.高并发 一个最典型的就是电商网站,例如双11, ...
- 使用AOF持久化文件实现还原Redis数据库并得到RDB持久化文件
目录 1 编写本文的初衷 2 具体实施 2.1 Redis持久化概念简介 2.2 获取指定Redis的AOF持久化文件 2.3 把Redis的持久化AOF文件转换为RDB文件 1 编写本文的初衷 因为 ...
- 分布式系统的CAP(Redis)
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点.而由于当前的网络硬件肯定会出现延迟丢包等问题,所以 分区容忍性是我们必须需要实现的. 所以我们只能在一致性和可用性之间进行权衡,没有NoSQ ...
- redis深入学习(一)-----CAP、redis数据类型
NoSQL数据库的四大分类 KV键值: memcache+redis 文档型数据库(bson格式比较多): MongoDB MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在 ...
- Spring + Jedis集成Redis(集群redis数据库)
前段时间说过单例redis数据库的方法,但是生成环境一般不会使用,基本上都是集群redis数据库,所以这里说说集群redis的代码. 1.pom.xml引入jar <!--Redis--> ...
随机推荐
- Spring5.0源码学习系列之Spring AOP简述
前言介绍 附录:Spring源码学习专栏 在前面章节的学习中,我们对Spring框架的IOC实现源码有了一定的了解,接着本文继续学习Springframework一个核心的技术点AOP技术. 在学习S ...
- selenium调用JS实现自动化
webdriver自带的api使用起来有局限性,比如下拉滚动条文本框输入,以及一些弹出框的操作,使用JS直接操作方便又灵活. 一:示例 from selenium import webdriver f ...
- docker中启动容器提示端口被占用
docker中启动容器提示端口被占用,但是 docker ps -a 查不到信息 1.查询端口被占用的id netstat -ntpl |grep 3306 2.杀掉该id kill -9 如果kil ...
- Java基础教程——字节流
IO流 水流 特点 连续性 逝者如斯夫,不舍昼夜: 方向性 一江春水向东流.水往低处流.百川东到海,何时复西归?少壮不努力,老大徒伤悲! 源头尽头 唯有源头活水来:覆水难收 Java里的IO也有这样的 ...
- mq消息消费,broker选址
PullRequest.MessageQueue.BrokerName 根据PullRequest.MessageQueue得到brokerId,默认0或者用缓存中的suggest,每次消息拉取后会更 ...
- 新手上路A4——多JDK环境变量的配置
目录 配置单个JDK的方法 配置2+JDK的方法 方法 补充 检查JDK版本是否切换成功 前面讲了如何选择Java版本. 以及JDK8和JDK11的下载安装配置 有想法的人就开始发动他们优秀的小脑袋瓜 ...
- 05 python开发之文件处理
05 python开发之文件处理 目录 05 python开发之文件处理 5 文件处理 5.1 字符编码 5.1.1 基本概念 5.1.2 发展历程 5.1.3 使用 5.2 文件处理基础 5.2.1 ...
- moviepy音视频剪辑:视频剪辑基类VideoClip的属性及方法详解
☞ ░ 前往老猿Python博文目录 ░ 一.概述 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>和<moviepy音视频剪辑:moviepy中的剪辑基类Cl ...
- 第11.21节 Python 中正则表达式的其他扩展功能
一. 引言 在<第11.17节 Python 正则表达式扩展功能:命名组功能及组的反向引用>中老猿介绍了组匹配模式的命名组功能及引用组功能,这两者都是正则表达式的扩展功能,其实在re模块中 ...
- Python特殊序列\d能匹配哪些数字?
在缺省语言环境下,老猿对\d的匹配范围做了个测试,下面的数字包含半角数字.全角数字.中文数字,测试语句如下: >>> m=re.search(r'(\d*)(\D*)(\d*)',' ...