美团CAT集成

CAT客户端集成(原官方集成方式)

官方Github参考:cat-master-java-README.zh-CN.md

1.在应用所在容器(主机 或 docker容器)中创建/data/appdatas/cat, /data/applogs/cat(记录日志,可选);
2.创建/data/appdatas/cat/client.xml

<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="config.xsd">
    <servers>
        <server ip="<cat server ip address>" port="2280" http-port="8080" />
    </servers>
</config>

3. 在Java项目中创建 src/main/resources/META-INF/app.properties 文件, 并添加如下内容:

app.name={appkey}

appkey 只能包含英文字母 (a-z, A-Z)、数字 (0-9)、下划线 (_) 和中划线 (-)
现在java的cat client会自动懒加载,已经没有必要手动初始化客户端。

4.添加Maven依赖

<dependency>
    <groupId>com.dianping.cat</groupId>
    <artifactId>cat-client</artifactId>
    <version>3.0.0</version>
</dependency>

CAT初始化分析与优化

CAT调用的入口类为Cat,如下代码:

 进入newTransaction | logEvent等方法内,均可以发现如下初始化方法getProducer->checkAndInitialize->SPI,并且CAT都是延迟初始化的,即SPI(Service Provider Interface)的执行是在Spring上下文初始化以后执行的:

即可以通过SPI机制移除之前提到的/data/appdatas/cat/client.xml和src/main/resources/META-INF/app.properties配置文件;通过自定义ClientConfigProvider实现类并结合Spring上下文将相应配置属性设置进入ClientConfigProvider实现类;

即通过自定义注解@MxCat(appId, env, serverIp, ...),将CAT配置文件中client.xml、app.properties的配置信息均集成到该自定义springboot启动注解中,并通过该启动注解@Import相应埋点设置;

CAT自动化拦截

URL Filter拦截

定义Filter拦截/*,

埋点信息如下: 


注:

IPS=x-forward-for(请求来源IP链)| remoteAddr(请求来源IP链中的最后一个请求代理的IP)
VirtualIP=remoteAddr(请求来源IP链中的最后一个请求代理的IP)

AOP拦截

(1)拦截Controller中@*Mapping修饰的方法

注:补充URL Filter中的URL.Param和URL.Result信息

(2)拦截@Service修饰的类中的所有public方法 或者 @MxCatService修饰的方法

埋点信息如下:

(3)拦截@MxCatCall修饰的方法(远程调用) 

埋点信息如下:

(4)拦截@MxCatCache修饰的方法(缓存操作)

埋点信息如下:

其他拦截

(4)Mybatis插件

通过自定义Mybatis插件CatMybatisInterceptor,并通过自动注册Bean的方式使其生效

埋点信息如下:

(5)Log4j2 Appender

Log4j2监控需要在log4j2.xml引入自定义MxCatAppender,该Appender会通过event记录Warn以上级别的错误日志,可通过Problem报表进行查看;

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="off" monitorInterval="1800">
    ...
    <Appenders>
        ...
        <!-- CAT log4j2 -->
        <MxCatAppender name="MxCatAppender"/>
    </Appenders>
    
    <Loggers>
        <Logger name="com.mx" level="trace" additivity="false">
             ...
            <AppenderRef ref="MxCatAppender"/>
        </Logger>
    </Loggers>
</Configuration>

(6)携程Apollo开关

由于Apollo客户端apollo-client默认集成了对Apollo的监控,因此提供了关闭此监控的开关;

跨服务调用

关于跨服务调用,无疑就是将监控上下文ID在多个request间进行传递,

客户端:
HttpClient添加Request拦截器(埋点remoteCallClient 且 通过request.headers传递context):

//埋点cat remoteCallClient并构建相关trace信息(需自定义Context实现类)
CatTraceContext catTraceContext = new CatTraceContext();
//catRemoteCallDomain为服务端domain
Cat.logRemoteCallClient(catTraceContext, catRemoteCallDomain);
//设置request.header且通过request.headers传递context
req.addHeader(CatTraceContext.ROOT,catTraceContext.getProperty(CatTraceContext.ROOT));
req.addHeader(CatTraceContext.PARENT, req.addHeader(CatTraceContext.PARENT));
req.addHeader(CatTraceContext.CHILD, catTraceContext.getProperty(CatTraceContext.CHILD));

服务端:
改造CatFilter(获取request.headers):

/** 添加服务追踪(Server端)处理逻辑 */
String rootHeader = req.getHeader(CatTraceContext.ROOT);
String parentHeader = req.getHeader(CatTraceContext.PARENT);
String childHeader = req.getHeader(CatTraceContext.CHILD);
/** 埋点服务追踪服务端 */
Cat.logRemoteCallServer(CatTraceContext.buildContext(rootHeader, parentHeader, childHeader));

关于跨服务调用,可参考: 基于Cat的分布式调用追踪

调用端的最终实现效果如下:

CAT跨服务调用埋点架构图:

发布了56 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/luo15242208310/article/details/102382884