大眾點評的老吳在InfoQ上講了Cat之後,有不少同仁開始關註這個實時監控系統,但學習的文章甚少,在GitHub上也是一言代過,給我們這些開發人員留下了N多個疑問,一時間不知道去哪裡問,向誰去問了,通常的百度和谷歌也不好使了,不過,好在經理推薦的QQ群幫了忙,認識了一些cat的前輩,經過他們的努力和
大眾點評的老吳在InfoQ上講了Cat之後,有不少同仁開始關註這個實時監控系統,但學習的文章甚少,在GitHub上也是一言代過,給我們這些開發人員留下了N多個疑問,一時間不知道去哪裡問,向誰去問了,通常的百度和谷歌也不好使了,不過,好在經理推薦的QQ群幫了忙,認識了一些cat的前輩,經過他們的努力和我們共同的執著,終於把這塊難啃的骨頭啃動了!
參考代碼:https://github.com/chinaboard/PureCat
完成的分散式消息樹
分散式消息樹實現的理論
Cat上下文,它與其它數據上下文,Http上下文,文件上下文的意思是一樣的,都是指一種對象的封裝,在cat里它的上下文由三個ID組成,ROOT,Parent和Child,他們類似於資料庫里的聯合主鍵,在讓多個消息進行關聯時,需要通過這些鍵值,我們在跨網路記錄日誌時,也需要把這三個對象傳過去,在目標伺服器上進行解析,然後這兩個消息就組成了一個消息樹了。
CatContext上下文內容
/// <summary> /// cat上下文 /// </summary> public class CatContext { /// <summary> /// 消息根ID /// </summary> public string CatRootId { get; set; } /// <summary> /// 上級消息ID /// </summary> public string CatParentId { get; set; } /// <summary> /// 當前消息ID /// </summary> public string CatChildId { get; set; } public string ContextName { get; set; } public CatContext(string contextName) { ContextName = contextName ?? Environment.MachineName; } public CatContext() : this(null) { } }
在進行分散式調用時,和java版的一樣,用到了LogRemoteCallClient和LogRemoteCallServer這兩個方法,前者是消息發起者調用,生成context後,將它序列化傳到另外一個節點,這個節點在進行事務處理時會將自己包裹到調用方的事務時在,這也就是分散式消息樹的實現原理。
需要註意的地方
在Cat里,有域的概念,即domain,我們在分散式消息樹的幾台伺服器,必須處在同一個域下!
代碼這樣實現的
A節點核心代碼
/* client1 -> catContext -> client2 * */ #region Cat實時監控 PureCat.PureCat.Initialize(); var context = PureCat.PureCat.DoTransaction("Do", "Test", func: () => { PureCat.PureCat.NewEvent("Do", "Test"); return PureCat.PureCat.LogRemoteCallClient("zzl"); }); var url = "http://localhost:4532/home/index"; var handler = new HttpClientHandler() { }; using (var http = new HttpClient(handler)) { http.DefaultRequestHeaders.Add("catContext", Lind.DDD.Utils.SerializeMemoryHelper.SerializeToJson(context)); var response = http.GetAsync(url).Result; var staus = response.IsSuccessStatusCode; } Console.ReadLine(); #endregion
B節點核心代碼
string reusult = Request.Headers.GetValues("catContext").FirstOrDefault(); var cat = Lind.DDD.Utils.SerializeMemoryHelper.DeserializeFromJson<PureCat.Context.CatContext>(reusult); PureCat.PureCat.DoTransaction("Do", "Add", () => { PureCat.PureCat.LogRemoteCallServer(cat); PureCat.PureCat.LogEvent("Do", "Add", "0", "hello distribute api123"); PureCat.PureCat.LogError(new Exception()); });
本文代碼只是大叔的測試DEMO,之後還會對它進行封裝與優化,敬請期待!
感謝您的閱讀!