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自動建立了兩個表,而且記錄了發佈的消息,和接收到的消息。這些數據會定時刪除。這些都是不須要咱們管的。