CAP介绍:git
CAP是一个用来解决微服务或者分布式系统中分布式事务问题的一个开源项目解决方案。能够解决跨服务器的数据一致性问题。一个简单的列子,如:订单系统建立订单后须要通知邮件通知用户下单成功,解决方案有下面几种:github
1:建立订单时同步调用邮件发送,邮件发送失败则整个订单建立失败,这样保证了一致性,但性能和可用性有很是大的问题。或者无论邮件发送状态,失败了就算了,这样用户就可能收不到通知邮件了。web
2:建立订单时经过消息队列推送一个订单建立成功的事件,另外建立一个服务来监听消费此事件,并执行邮件发送的功能。这种方案存在往消息队列推送数据失败的可能,存在和方案1同样的问题。sql
3:建立订单时同时往一个叫“订单建立成功”的事件表中插入相关数据,二者在同一事务中。 另外建立一个服务定时查询此表,发现有待处理的数据时,执行邮件发送,成功后把此数据删除或更新为已处理。此方案保证了最终一致性和可用性,但得定时扫描,性能和及时性有问题。数据库
4:建立订单时同时往一个叫“订单建立成功”的事件表中插入相关数据,二者在同一事务中。而且经过消息队列推送此消息,若是推送失败,则定时扫描“订单建立成功”表将失败的数据从新推送。另外建立一个服务来监听消费此事件,这种方案集成了方案1和方案2的优势,即保证了最终一致性,也保证了可用性。api
从上面来看最优的方案显示是方案4,咱们此次的主角CAP也正是采用了此种方案来实现的,咱们这里介绍的方案4仍是比较简单的,CAP的实现要更加的严谨、更增强大,咱们不须要建过程表,也不须要处理消息队列的问题,底层不少的细节都不须要咱们考虑,只管用就行了。CAP数据库存储支持:Sql Server,MySql,PostgreSql,MongoDB。消息队列支持:RabbitMQ,Kafka,Azure Service Bus等。服务器
各多CAP的介绍能够参考官网,详细的CAP理论能够参考其它文章。 官网 http://cap.dotnetcore.xyz/ ,开源地址:https://github.com/dotnetcore/CAP ,做者blog https://www.cnblogs.com/savorboard/async
快速开始分布式
CAP2.6是2019-8-29发布的,目前官网上的文档快速开始已经没法使用,由于里面用了 Savorboard.CAP.InMemoryMessageQueue 组件,该组件仍是2.51,不支持最新的CAP2.6版本,应该得过段时间才会修复文档,或者等 Savorboard.CAP.InMemoryMessageQueue组件更新。如今咱们就在这开始咱们的“快速开始”吧。咱们将基于rabbitmq和sqlserver数据库来实现。微服务
1:建立项目
打开VS建立一个名叫CapDemo的webapi项目,版本选择ASP.NET Core 2.2。CAP2.6不支持2.2如下的.net core
2:添加CAP引用
在Nuget中添加 DotNetCore.CAP DotNetCore.CAP.RabbitMQ DotNetCore.CAP.SqlServer 的引用。
3:配置CAP
在Startup.cs的ConfigureServices方法中添加如下代码
services.AddCap(c => { c.UseSqlServer(@"Data Source=.\sql2014;Initial Catalog=Test;User ID=sa;Password=sa"); //使用SqlServer数据库,链接地址请依实际修改 c.UseRabbitMQ( mq => { mq.HostName = "192.168.150.134"; //RabitMq服务器地址,依实际状况修改此地址 mq.Port = 5672; mq.UserName = "admin"; //RabbitMq帐号 mq.Password = "admin"; //RabbitMq密码 }); });
4:发布事件
将 CapDemo.Controllers.ValuesController中的全部方法所有删除。添加引用 using DotNetCore.CAP; ,并添加如下方法
[HttpGet] public async Task<string> Get([FromServices]ICapPublisher capPublish) { await capPublish.PublishAsync<string>("Order.Created", "hello,订单建立成功啦"); //发布Order.Created事件 return "订单建立成功啦"; }
5:订阅事件
在CapDemo.Controllers.ValuesController中添加如下方法:
[NonAction] [CapSubscribe("Order.Created")] //监听Order.Created事件 public async Task OrderCreatedEventHand(string msg) { Console.WriteLine(msg); }
6:最后一步:启动测试
在OrderCreatedEventHand方法内打个断点,F5启动项目访问https://localhost:44304/api/values界面。由于此例中第一次访问时可能发布事件比订阅事件要快,致使还没订阅就把事件发布出去了,这样的事件会丢失,因此咱们再F5刷新一下界面,能够看到程序就进入到了订阅事件里面。
后记:
添加监控仪表盘监控CAP运行情况:
1:只须要在Startup.cs的AddCap方法中添加配置: c.UseDashboard(); 就万事大吉了,一个功能强大的事件管理界面就出来了,具体以下图:
2: 从新编译并启动项目,进入https://localhost:44304/cap ,从打开的界面里能够看到CAP的各类事件和状态。
数据库变化
咱们再看看数据库里面的变化吧,从下图能够看出CAP自动建立了两个表,而且记录了发布的消息,和接收到的消息。这些数据会定时删除。这些都是不须要咱们管的。