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--> ...
随机推荐
- 记XShell无法连接虚拟机中的Linux,但Linux系统中可以连接外网。
如题. 原本设置如下: 本地机IP 为192.168.43.XXX VMWare中"虚拟机网络编辑器"中子网设置为192.168.39.0. 虚拟机中IP为192.168.39.1 ...
- python3错误AttributeError: 'TestSequenceFunctions' object has no attribute 'seq'
对比了两段代码发现,原来是setUp要用用大写才能被正确引用. 修改后,代码运行成功.
- C语言精华——内存管理,很多学校学习不到的知识~
在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度.在这种情况下,要达到有效的资源利用--使用内存管理,必须在运行时动态地分配所需内存,并在使用完毕后尽早释放不需要的内存 ...
- rest-framework:权限组件
一 权限简介 只用超级用户才能访问指定的数据,普通用户不能访问,所以就要有权限组件对其限制 二 局部使用 from rest_framework.permissions import BasePerm ...
- 【2020.11.28提高组模拟】T1染色(color)
[2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...
- 05 python开发之文件处理
05 python开发之文件处理 目录 05 python开发之文件处理 5 文件处理 5.1 字符编码 5.1.1 基本概念 5.1.2 发展历程 5.1.3 使用 5.2 文件处理基础 5.2.1 ...
- 使用Jmeter测试快速入门
一 创建线程组 1.1.2. 线程组主要包含三个参数:线程数.准备时长(Ramp-Up Period(in seconds)).循环次数. 1.1.3. 线程数:虚拟用户数.一个虚拟用户占用 ...
- 洛谷 P3410 拍照(最大流 + 建图)
这道题问的是一群人要和另一群人合影,每个客人都有必须在场的人全部在场才能在场,每个客人给的有收入,但是邀请也需要支出,问最大收入? 我觉得可以总结为一类问题,就是有先决条件的网络流问题.看到费用和支出 ...
- Python中迭代循环使用比较多的range函数的作用
range函数用于生成一个不可变的数字序列可迭代对象,类型为range,该数字序列通常用于在 for 循环中循环指定的次数. 具体可参考:<Python中与迭代相关的函数>的详细介绍 老猿 ...
- Python学习随笔:PyCharm的错误检测使用及调整配置减少错误数量
老猿使用PyCharm有将近一个月了,发现PyCharm并不能很好的完成语法检查,有时运行时突然终止,仔细核查却发现是基本的语法错误,不过有次无意中移动鼠标到代码最右边的边框时发现其实PyCharm有 ...