對基於請求的分散式消息樹的分析 在MVC時有過濾器System.Web.Mvc.ActionFilterAttribute,它可以對action執行的整個過程進行攔截,執行前與執行後我們可以註入自己的代碼,這是我們實現對請求做監控的前提,對於一個請求來說,如果它是從Get或者Post過來的,我們會在 ...
對基於請求的分散式消息樹的分析
在MVC時有過濾器System.Web.Mvc.ActionFilterAttribute,它可以對action執行的整個過程進行攔截,執行前與執行後我們可以註入自己的代碼,這是我們實現對請求做監控的前提,對於一個請求來說,如果它是從Get或者Post過來的,我們會在發起端將初始catContext進行鏈條式的傳遞,從第一個節點開始生成並傳遞,最後到尾結節,開始執行cat,生成新的context,將新的context回寫到響應頭,由上一個節點拿到這個響應頭,開始寫自己的cat,這個過程最後執行到第一個節點,整個過程結束!
對消息樹流程的設計
代碼的實現
下麵開始設計咱們的Filter攔截器,用來生成catContext,並將處理後的context寫響應頭中
/// <summary> /// Cat攔截器,主要攔截Http請求 /// </summary> public class CatFilter : System.Web.Mvc.ActionFilterAttribute { /// <summary> /// 請求來到時 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); } /// <summary> /// 請求結束時 /// 調用次序:A->B->C->c->b->a,從c開始執行,把context結果在響應頭裡依據向回傳 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext) { var context = PureCat.CatClient.GetCatContextFromServer(); if (context != null) { context = PureCat.CatClient.DoTransaction("youDomain", filterContext.HttpContext.Request.Url.AbsoluteUri, () => { PureCat.CatClient.LogRemoteCallServer(context); PureCat.CatClient.LogEvent(filterContext.HttpContext.Request.Url.AbsoluteUri, "Action Finish..."); if (filterContext.Exception != null) { PureCat.CatClient.LogError(filterContext.Exception); } }); #region 響應頭寫數據 if (filterContext.HttpContext.Response.Headers.GetValues("catContext") != null && filterContext.HttpContext.Response.Headers.GetValues("catContext").Length > 0) { filterContext.HttpContext.Response.Headers.Remove("catContext"); } filterContext.HttpContext.Response.Headers.Add("catContext", Lind.DDD.Utils.SerializeMemoryHelper.SerializeToJson(context)); #endregion } base.OnActionExecuted(filterContext); } }
最後就是修改我們之前封裝的GET和POST方法,讓它處理一下響應頭,使用響應頭的context作為當前cat的上下文
/// <summary> /// Get數據 /// </summary> /// <param name="requestUri"></param> /// <returns></returns> public static HttpResponseMessage Get(string requestUri, bool isCat) { var handler = new HttpClientHandler() { }; using (var http = new HttpClient(handler)) { PureCat.CatClient.SetCatContextToServer(http, GetCurrentContext("Get Request Sent...", isCat));//設置介面api的頭,發送 var response = http.GetAsync(requestUri).Result; var context = response.Headers.Where(i => i.Key == "catContext"); if (context != null && context.Count() > 0) { var cat = Lind.DDD.Utils.SerializeMemoryHelper.DeserializeFromJson<CatContext>(context.First().Value.FirstOrDefault()); PureCat.CatClient.SetCatContextToServer(System.Web.HttpContext.Current, cat); } return response; } }
日誌的生成
最後生成的cat日誌也是我們可以理解的,即從a,b,c,d的調用,在執行結束的監控順序是d,c,b,a,呵呵,並且在在step2時故意放了一個異常出來,讓cat記錄一下,呵呵。