前言
今天,我們很高興宣布 CAP 發布 5.1 版本正式版,在這個版本里我們同樣引入了更多令人激動的新特性和改進,同時也得到越來越多人的喜愛。
得益於社區的反饋和貢獻者的支持,在過去的兩個月里,我們NuGet的下載量增加了20萬,貢獻者團隊達到了57人,同時我們也發現了非常多的國外貢獻者的參與,這說明 CAP 在海外的用戶也正在迅速增長,在此我表示非常的感謝。
在 5.1 版本中,我們帶來了大家期待已久的 Filter 功能,以及對 Redis Streams 的支持,同時我們重寫了 Dashboard,下面我們就具體來看一下吧。
總覽
可能有些人還不知道 CAP 是什么,老規矩來一個簡介。
CAP 是一個用來解決微服務或者分布式系統中分布式事務問題的一個開源項目解決方案(https://github.com/dotnetcore/CAP)同樣可以用來作為 EventBus 使用,該項目誕生於2016年,目前在 Github 已經有超過 4800 Star 以及超過 95萬 的下載量,已經在越來越多公司的和項目中得到應用。
如果你想對 CAP 更多了解,請查看我們的 官方文檔。
本次在 CAP 5.1 版本中我們主要帶來了以下新特性:
- 增加了對訂閱者 Filter 的支持
- 增加了對 Redis Streams Transport 的支持
- 改進 新版基於 Vue 的 Dashboard
- 改進 Kafka Transport 對通配符的訂閱的支持
- 改進 RabbitMQ 對異構系統的支持
- 其他功能改進和若干 Bug 修復
增加了對訂閱者 Filter 的支持
根據社區得到的反饋,在一些場景下需要對訂閱者方法應用一些 AOP 攔截功能以達到某種目的,例如記錄日志或自動開啟事務等功能。
在過去,我們通過對第三方 AOP 組件提供支持來做到這一點,例如我們寫了一篇 博客 來描述如何在 CAP 5.0版本中使用 Castle 來對訂閱方法進行攔截,這使我們得到了一些贊揚。但同時我們也發現了這種方式存在一些缺點,例如無法方便的在代理類中進行構造函數注入以及方法需要設定為 virtual 另外還有攔截器生命周期控制等問題。
基於以上原因,現在 CAP 直接提供了對訂閱者 Filter 的支持,這使得問題大大簡化以及獲得了配置體驗上的提升,下面簡單看一下如何使用。
- 新建一個自定義過濾器類,繼承
ISubscribeFilter
接口
public class MyCapFilter: ISubscribeFilter
{
public void OnSubscribeExecuting(ExecutingContext context)
{
// 訂閱方法執行前
}
public void OnSubscribeExecuted(ExecutedContext context)
{
// 訂閱方法執行后
}
public void OnSubscribeException(ExceptionContext context)
{
// 訂閱方法執行異常
}
}
- 在CAP配置中添加上面的自定義過濾器類
services.AddCap(opt =>
{
// ***
}.AddSubscribeFilter<MyCapFilter>();
以上就是全部的集成工作,是不是變得非常容易。
增加了對 Redis Streams Transport 的支持
首先感謝來自埃及的 Mahmoud Samir 對此功能提供的 PR 支持。
我們知道,根據可用性原則,你的系統依賴的組件數量越少,那么整體出現問題的概率就越低,你越能夠對其進行控制。 那么這也是我們此次考慮對引入 Redis 的考慮之一,對於小型系統來說引入額外的中間件會增加復雜性,很多用戶並不願意。
那么,為什么我們在過去沒有對Redis支持呢? 這主要是一段時間以來,Redis 發布/訂閱模式的功能有限,也就是 pub/sub 無法滿足需求,該功能的典型缺點是沒有一種確認(Acknowledge)機制來保證消息是被送達的。
Stream 是 Redis 5.0 引入的一種新的數據類型,它以一種更抽象的方式建模日志數據結構。 除了提供確認功能外,還提供了我們所需的 Consumer Groups 功能,所以我們將其放到了我們的支持列表中。
集成方式:
PM> Install-Package DotNetCore.CAP.RedisStreams
services.AddCap(x =>
{
// ...
x.UseRedis(...);
});
新版基於 Vue 的 Dashboard
在這個版本中,我們對我們的Dashboard進行了更換,熟悉 hangfire的同學可能知道CAP的dashboard最初來自於改寫的hangfire ui,這主要是由於在 .NET Core的早期階段沒有一種合適的方式來將 Razor 頁面嵌入到 (DLL) NuGet 包中,Hangfire采用了一種將 Razor頁面生成為 C# 代碼並且編譯到程序集中的方式來解決這一問題,這主要利用到了一款第三方 Visual Studio 擴展工具,但該工具自2019年以來已經沒有繼續更新。
另外的原因是由於 Dashbaord 目前的生成方式不利於對代碼進行維護,有時會出現莫名其妙的編譯問題,而且需要安裝VS擴展工具,這讓我們的貢獻者參與其中變得沮喪。
在新版本重寫開始之前,我們調研了 Blazor 的方案,但最終沒有采納。 這是由於 Blazor 集成需要額外配置的東西太多而且較為分散,很難提供一種非常簡便的配置方式,這對於CAP作為一個庫來說不是非常合適。在此感謝 BootstrapBlazor 的作者張同學對此提供的支持和建議。
所以,我們最終選擇了使用 Vue 來重寫我們的 Dashboard ,但這對於我來說這是一項較為挑戰的工作,因為我從沒寫過前端代碼,最終花了一周左右的時間完成了整個工作,ps: 代碼可能較為粗糙,前端好的同學歡迎提交 PR 重構。
樣例圖:
Transport 中的改動
改進 Kafka 對通配符的訂閱的支持
過去只有 RabbitMQ 支持此功能,那么現在在 Kafka 訂閱方法中,你也可以使用 *
和 #
通配符來進行批量訂閱。
*
可以代替一個或多個詞
#
可以代替零或多個詞
看圖理解(圖片來源 RabbitMQ 官網):
在這個例子中,我們將發送所有描述動物的消息。消息將使用由三個詞(兩個點)組成的路由名稱發送。名稱中的第一個詞將描述 敏捷(celerity),第二個詞描述顏色(colour),第三個詞描述物種(species):“
. . ”。
我們創建了三個綁定:Q1 與綁定鍵“ .orange. ”綁定,Q2 與“ ..rabbit ”和“ lazy.# ”綁定。
這些綁定可以總結為:
Q1 對所有橙色動物都感興趣。
Q2 想收聽關於兔子的一切,以及關於懶惰動物的一切。
改進 RabbitMQ 對異構系統的支持
由於CAP處理消息需要有一些固定的信息,如果發送過來的消息沒有攜帶這些信息,那么就會報錯。然而如果你的上游不使用CAP,或者需要其他系統進行對接,那么怎么辦呢?
在這個版本中,我們對 RabbitMQ 增加了 CustomHeaders
配置項,你可以使用這個配置對必須的頭信息進行填充,用法如下:
cap.UseRabbitMQ(x =>
{
x.HostName = "xxxx";
x.UserName = "xxxx";
x.Password = "xxxx";
x.CustomHeaders = e => new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(Headers.MessageId, SnowflakeId.Default().NextId().ToString()),
new KeyValuePair<string, string>(Headers.MessageName, e.RoutingKey),
};
});
其他
其他的一些改進項目包括:
1、我們將所有的 nuget 的依賴包都升級到了最新版本。
2、修復了一些已知的Bug,你可以在這里看到。
總結
以上,就是本版本中支持的一些新特性,感謝大家的支持,我們很開心能夠幫助到大家
。大家在使用的過程中遇到問題希望也能夠積極的反饋,幫助CAP變得越來越好。😃
如果你喜歡這個項目,可以通過下面的連接點擊 Star 給我們支持。
如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】。
如果你對 .NET Core 有興趣的話可以關注我,我會定期的在博客分享我的學習心得。
本文地址:http://www.cnblogs.com/savorboard/p/cap-5-1.html
作者博客:Savorboard
本文原創授權為:署名 - 非商業性使用 - 禁止演繹,協議普通文本 | 協議法律文本