实时监控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
对于分布式消息树上下文的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,之后还会对它进行封装与优化,敬请期待!
感谢您的阅读!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2012-03-01 你必须要知道的架构知识~第二章 代码是否面向对象,要看你的继承怎么用