深入详解美团点评CAT跨语言服务监控(三)CAT客户端原理

上一篇:CAT跨语言服务链监控(二) CAT服务端初始化          下一篇:CAT跨语言服务链监控(四)服务端消息分发

CAT客户端实现

cat客户端部分核心类

  • message目录下面有消息相关的部分接口 
  • internal目录包含主要的CAT客户端内部实现类;
  • io目录包含建立服务端连接、重连、消息队列监听、上报等io实现类;
  • spi目录为上报消息工具包,包含消息二进制编解码、转义等实现类。

 

 

 

 

 

消息的组织 - 消息树

大众点评Cat使用消息树(MessageTree)组织日志,下面为消息树的类定义

我们每次操作的实体都是消息树,其中有个domain字段,这是cat中一个非常重要的概念,一个domain可以对应成一个project,每个消息树拥有一个唯一的MessageId, 不同的消息树(比如微服务中A服务调用B服务,A,B都会生成消息树) 通过 parenMessageId、rootMessageId 串联起来,消息树下的所有实体都是Message,一共有5种类型的Message, 分别是Transaction, Event, Trace, Metric和Heartbeat。

Transaction:可以理解为是一个事务,事务之间可以互相嵌套,事务还可以嵌套任意其他消息类型,存放在List<Message> m_children 成员变量中,也只有事务才可以嵌套。一般用来记录跨越系统边界的程序访问行为,比如远程调用,数据库调用,也适合执行时间较长的业务逻辑监控。

Event:代表系统是在某个时间点发生的一次事件,例如新用户注册、登陆,系统异常等,理论上可以记录任何事情,它和transaction相比缺少了时间的统计,开销比transaction要小。还可以用来记录两个事务之间的关系,分支事务通过设置消息树的parentMessageId维护与主事务消息之间的关系。

Trace:用于记录一些trace、debug这类的信息,比如log4j打印日志。以便于快速调试定位问题

Metric:用于记录业务指标、指标可能包含对一个指标记录次数、记录平均值、记录总和

Heartbeat:主要用于记录系统的心跳信息,比如CPU%, MEM%,连接池状态,系统负载等。

 

客户端的初始化

客户端操作对象Cat封装了所有的接口。我们先通过下面源码来了解下Cat的初始化过程。

class Cat{
    public static Transaction newTransaction(String type, String name) {
        return Cat.getProducer().newTransaction(type, name);
    }
    
    public static MessageProducer getProducer() {
        checkAndInitialize();

        return s_instance.m_producer;
    }
    
    private static void checkAndInitialize() {
        if (!s_init) {
            synchronized (s_instance) {
                if (!s_init) {
                    initialize(new File(getCatHome(), "client.xml"));
                    log("WARN", "Cat is lazy initialized!");
                    s_init = true;
                }
            }
        }
    }
    
    public static void initialize(File configFile) {
        PlexusContainer container = ContainerLoader.getDefaultContainer();

        initialize(container, configFile);
    }

    public static void initialize(PlexusContainer container, File configFile) {
        ModuleContext ctx = new DefaultModuleContext(container);
        Module module = ctx.lookup(Module.class, CatClientModule.ID);

        if (!module.isInitialized()) {
            ModuleInitializer initializer = ctx.lookup(ModuleInitializer.class);

            ctx.setAttribute("cat-client-config-file", configFile);
            initializer.execute(ctx, module);
        }
    }
}

 

从上面代码可以看到, 创建transaction首先会通过getProducer函数获取消息生产者MessageProducer对象,在返回MessageProducer对象之前,函数会对客户端进行初始化,设置 CatHome目录,默认是/data/appdatas/cat ,读取配置文件 client.xml,接下来的初始化流程和服务器类似, 也是先通过 ContainerLoader.getDefaultContainer(); 初始化plexus容器。客户端需要被装入容器的对象在下图的配置中:

 

-----------------------------------------------------------------------------------------------

我们借助components-cat-client.xml 配置来看部分类的实例化与初始化顺序:

 

上面流程中非常多的 initialize()  方法,有些是主动调用的,有些则是由容器框架调用的,这个在讲plexus容器的时候说过,如果类方法实现了 Initializable 接口,创建实例后会执行类的 initialize() 方法做一些初始化的工作。

------------------------------------------------------------------------------------------------

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值