美文网首页微服务中间件
调用链监控 CAT 之 URL埋点实践

调用链监控 CAT 之 URL埋点实践

作者: 程序员果果 | 来源:发表于2019-04-16 07:41 被阅读106次

URL监控埋点作用

  • 一个http请求来了之后,会自动打点,能够记录每个url的访问情况,并将以此请求后续的调用链路串起来,可以在cat上查看logview
  • 可以在cat交易及事件页面上都看到URL和URL.Forward(如果有前请求的话)两类数据;交易数据中URL点进去的数据就是被访问的具体URL(去掉参数的前缀部分)
  • 请将catFilter存放filter的第一个,这样可以保证最大可能性监控所有的请求

实践

工程说明

工程名 端口 作用
cat-ui 8082 调用入口服务
cat-business-consumer 8083 业务消费服务
cat-order-service 8084 订单服务
cat-storage-service 8085 库存服务

上图是本节实例的埋点图,首先 cat-ui 的入口 和 调用点 加入cat埋点,cat-business-consumer的入口和调用点加入埋点,cat-order-service 和 cat-storage-service 不再调用其他微服务,所以只在入口加入埋点。通过这样的埋点,可以组成一条完整的调用链。

关键代码

调用链上下文通用类

CatContextImpl.java
/**
 * Cat.context接口实现类,用于context调用链传递,相关方法Cat.logRemoteCall()和Cat.logRemoteServer()
 */
public class CatContextImpl implements Cat.Context {

    private Map<String, String> properties = new HashMap<>(16);

    @Override
    public void addProperty(String key, String value) {
        properties.put(key, value);
    }

    @Override
    public String getProperty(String key) {
        return properties.get(key);
    }
}
CatHttpConstants
/**
 * 添加header常量,用于http协议传输rootId、parentId、childId三个context属性
 */
public class CatHttpConstants {

    /**
     * http header 常量
     */
    public static final String CAT_HTTP_HEADER_ROOT_MESSAGE_ID = "X-CAT-ROOT-MESSAGE-ID";
    public static final String CAT_HTTP_HEADER_PARENT_MESSAGE_ID = "X-CAT-ROOT-PARENT-ID";
    public static final String CAT_HTTP_HEADER_CHILD_MESSAGE_ID = "X-CAT-ROOT-CHILD-ID";

}
CatServletFilter
/**
 * http协议传输,远程调用链目标端接收context的filter,
 * 通过header接收rootId、parentId、childId并放入CatContextImpl中,调用Cat.logRemoteCallServer()进行调用链关联
 * 注:若不涉及调用链,则直接使用cat-client.jar中提供的filter即可
 * 使用方法(视项目框架而定):
 *      1、web项目:在web.xml中引用此filter
 *      2、Springboot项目,通过注入bean的方式注入此filter
 */
public class CatServletFilter implements Filter {


    private String[] urlPatterns = new String[0];

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String patterns = filterConfig.getInitParameter("CatHttpModuleUrlPatterns");
        if (patterns != null) {
            patterns = patterns.trim();
            urlPatterns = patterns.split(",");
            for (int i = 0; i < urlPatterns.length; i++) {
                urlPatterns[i] = urlPatterns[i].trim();
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        String url = request.getRequestURL().toString();
        for (String urlPattern : urlPatterns) {
            if (url.startsWith(urlPattern)) {
                url = urlPattern;
            }
        }

        CatContextImpl catContext = new CatContextImpl();
        catContext.addProperty( Cat.Context.ROOT, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID));
        catContext.addProperty(Cat.Context.PARENT, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID));
        catContext.addProperty(Cat.Context.CHILD, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID));
        Cat.logRemoteCallServer(catContext);

        Transaction t = Cat.newTransaction( CatConstants.TYPE_URL, url);

        try {

            Cat.logEvent("Service.method", request.getMethod(), Message.SUCCESS, request.getRequestURL().toString());
            Cat.logEvent("Service.client", request.getRemoteHost());

            filterChain.doFilter(servletRequest, servletResponse);

            t.setStatus(Transaction.SUCCESS);
        } catch (Exception ex) {
            t.setStatus(ex);
            Cat.logError(ex);
            throw ex;
        } finally {
            t.complete();
        }
    }

    @Override
    public void destroy() {

    }
}

本节实例中每个工程都会用到调用链上下文通用类。

cat-ui 工程

CatRestInterceptor
@Component
public class CatRestInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        Transaction t = Cat.newTransaction(CatConstants.TYPE_REMOTE_CALL, request.getURI().toString());

        try {
            HttpHeaders headers = request.getHeaders();

            // 保存和传递CAT调用链上下文
            Cat.Context ctx = new CatContextImpl();
            Cat.logRemoteCallClient(ctx);
            headers.add(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID, ctx.getProperty(Cat.Context.ROOT));
            headers.add(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID, ctx.getProperty(Cat.Context.PARENT));
            headers.add(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID, ctx.getProperty(Cat.Context.CHILD));

            // 保证请求继续被执行
            ClientHttpResponse response =  execution.execute(request, body);
            t.setStatus(Transaction.SUCCESS);
            return response;
        } catch (Exception e) {
            Cat.getProducer().logError(e);
            t.setStatus(e);
            throw e;
        } finally {
            t.complete();
        }

    }
}

CatServletFilter 对 cat-ui 的入口进行了埋点,CatRestInterceptor 实现 ClientHttpRequestInterceptor接口 可以对 RestTemplate 发起的请求进行拦截,利用这一点对调用点埋点,同时在 Http Header 中存入 调用链的上下文,将调用链传递下去。

cat-business-consumer、cat-order-service、cat-storage-service 中的埋点与 cat-ui 埋点的方式相同。

测试

发起请求

curl http://127.0.0.1:8082/start

cat 监控界面可以看到本节实例的服务。

点开 “logView” 可以看到完整的调用链信息。

点击 “Graph” 查看图表形式的调用链信息。

源码

https://github.com/gf-huanchupk/SpringCloudLearning/tree/master/chapter15

参考

https://github.com/dianping/cat/wiki

欢迎扫码或微信搜索公众号《程序员果果》关注我,关注有惊喜~


相关文章

  • 调用链监控 CAT 之 URL埋点实践

    URL监控埋点作用 一个http请求来了之后,会自动打点,能够记录每个url的访问情况,并将以此请求后续的调用链路...

  • 07、点评CAT之URL监控埋点

    一、 URL监控埋点方案1、作用一个http请求来了之后,会自动打点,能够记录每个url的访问情况,并将以此请求...

  • 调用链监控 CAT 之 入门

    文章首发于微信公众号《程序员果果》地址:https://mp.weixin.qq.com/s/G15cw9yXpq...

  • 监控

    监控的维度: 前端 业务 应用层(日志:logstash/kafaka/es/Kibana。调用链:cat/zip...

  • 前端埋点技术文档

    前端监控和前端埋点方案设计 阿里前端监控实践

  • 应用监控

    调用链监控的对比: CAT: Zipkin: Span:基本工作单元,一次链路调用,通过一个64位ID标识它。 T...

  • CAT实时监控系统:cat-client埋点设计

    1.相关概念 如下在Cat中我们称为: logview消息树(或者MessageTree),即应用内部的调用链路。...

  • web 埋点

    数据埋点是什么?设置数据埋点的意义?web 埋点实现原理了解一下 前端监控和前端埋点方案设计美团点评前端无痕埋点实践

  • 2020-07-29 开源监控工具链介绍

    说到监控现在最火的是全链路监控(服务调用+HTTP调用+数据源访问+MQ链路的监控),但我认为这是狭义的全链路监控...

  • 全方位的开源监控工具链介绍

    说到监控现在最火的是全链路监控(服务调用+HTTP调用+数据源访问+MQ链路的监控),但我认为这是狭义的全链...

网友评论

    本文标题:调用链监控 CAT 之 URL埋点实践

    本文链接:https://www.haomeiwen.com/subject/tcnmwqtx.html