文章出處

大眾點評的老吳在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

對于分布式消息樹上下文的Name,我們可以使用Guid碼生成,避免沖突!

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,之后還會對它進行封裝與優化,敬請期待!

感謝您的閱讀!


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()