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--> ...
随机推荐
- CentOS7.X 下安装MySQL8.0(附文件)
这是64位的安装包.如果需要32位的可以去官网下载哦.步骤一样 1 获取安装资源包 mysql-8.0.18-1.el7.x86_64.rpm-bundle.tar 链接: https://pan.b ...
- eclipse 老坑巨滑之内存溢出OOM
绪:今天接手一个古老项目,tomcat6+jdk6.被 java.lang.OutOfMemoryError: PermGen space 啪啪打脸, 网上确实有很多解决方法,主要有三种类型:一 ...
- 面试官:说一下List排序方法
1. 前言 排序算是比较高频的面试题了,节前面试了的两家公司都有问到排序问题,整理后分享给大家(文末见总结). 通常我们想到实现排序就是 Collections 工具类的 sort() 方法,而 so ...
- Redis分布式锁—Redisson+RLock可重入锁实现篇
前言 平时的工作中,由于生产环境中的项目是需要部署在多台服务器中的,所以经常会面临解决分布式场景下数据一致性的问题,那么就需要引入分布式锁来解决这一问题. 针对分布式锁的实现,目前比较常用的就如下几种 ...
- C++的编程指南
序言:每天更新C++的内容 一.文件结构 每个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.另一个文件用于保存程序的实现(implementatio ...
- git全流程
服务器:Ubuntu 使用git前准备工作: 下载git之前先更新: apt-get update 安装git: apt-get install git 创建本地仓库: mkdir test git初 ...
- 关于javaSMTP协议发邮件你必须知道的知识点
1.阅读官方吐槽 Note also that THERE IS NOT SUFFICIENT DOCUMENTATION HERE TO USE THESE FEATURES!!! You will ...
- PyQt(Python+Qt)学习随笔:Qt Designer中部件与国际化有关的设置translatable、 disambiguation和comment含义
在Qt Designer的部件的多个属性中,如toolTip.whatsThis.accessibleName.accessibleDescription.text等都有国际化属性设置,国际化属性有三 ...
- this.$options.data()实战之重置data
刚刚看到这个方法学习了一下,然后想到正在开发的项目有一个需要重置data的操作,正好拿来使用一下,节省了好多代码,美滋滋...
- 从.NET转GO了
前言 近几个月刚从.NET转到GO,入职了一个使用GO微服务的互联网公司.因为需要熟悉公司的微服务架构和适应新公司的节奏,所以最近没时间写博客,现在简单做个总结. 转GO的经历 自学GO 上一年的八月 ...