你的位置:首页 > ASP.net教程

[ASP.net教程]实时监控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,之后还会对它进行封装与优化,敬请期待!

感谢您的阅读!