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--> ...
随机推荐
- Linux下的MediaWiki的部署启动遇到的问题与解决方案
1. MySQL安装不成功 解决方案:https://bbs.csdn.net/topics/394377536 2. no space left on device ubuntu 解决方案:http ...
- LeetCode 018 4Sum
题目描述:4Sum Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c ...
- rest-framework 分页器
一 简单分页(查看第n页,每页显示n条) from rest_framework.pagination import PageNumberPagination # 一 基本使用:url=url=htt ...
- Django匆匆一眼却解答了多年疑惑
Django 是 Python 的 一款 Web 开发框架,另外还有 Tornado,Flask,Twisted.为什么我要选择学 Django?原因很简单,上家公司来了个网易的测开,就是用 Djan ...
- Spring Cloud 学习 (九) Spring Security, OAuth2
Spring Security Spring Security 是 Spring Resource 社区的一个安全组件.在安全方面,有两个主要的领域,一是"认证",即你是谁:二是& ...
- dubbo源码学习(一)dubbo容器启动流程简略分析
最近在学习dubbo,dubbo的使用感觉非常的简单,方便,基于Spring的容器加载配置文件就能直接搭建起dubbo,之前学习中没有养成记笔记的习惯,时间一久就容易忘记,后期的复习又需要话费较长的时 ...
- Django+Nginx+uWSGI生产环境部署
生产环境中的数据流 参考文档: wsgi详解:https://blog.csdn.net/li_101357/article/details/52748323 wsgi协议介绍(萌新版):https: ...
- python装饰器基础及应用
一.简介 装饰器是是修改其它函数功能的函数:其意义是让其他函数在不修改任何代码的前提下增加额外功能 二.数据类型 首先我们来看一段简单的代码: from types import MethodType ...
- eclispe中打点不会提示的解决方法,以及自动补全
Eclipse中打点无提示的解决办法 建了个JAVA工程,然后发现输入代码后,在输入.后面不会弹出来我所要的函数. alt+/ 提示No Default Proposals 自己找了半天, ...
- 老猿Python部分代码样例
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 PyQt编程实战:通过eventFilter监视QScrollArea的widget()的Paint ...