URL监控埋点作用

  • 一个http请求来了之后,会自动打点,能够记录每个url的访问情况,并将以此请求后续的调用链路串起来,可以在cat上查看logview
  • 可以在cat Transaction及Event 页面上都看到URL和URL.Forward(如果有Forward请求的话)两类数据;Transaction数据中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埋点实践的更多相关文章

  1. 第四模块 :微服务调用链监控CAT架构和实践

    采样率:每一个请求为都进行记录,或者100次请求为记录50次 各个开源框架都满足opentracing的标准,只要使用opentracing标准埋点的客户端,可以使用不同的客户端去展示,opentra ...

  2. 调用链监控 CAT 之 入门

    简介 CAT 是一个实时和接近全量的监控系统,它侧重于对Java应用的监控,基本接入了美团上海所有核心应用.目前在中间件(MVC.RPC.数据库.缓存等)框架中得到广泛应用,为美团各业务线提供系统的性 ...

  3. dubbo+zipkin调用链监控(二)

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  4. .Net Core 商城微服务项目系列(十):使用SkyWalking构建调用链监控(2019-02-13 13:25)

    SkyWalking的安装和简单使用已经在前面一篇介绍过了,本篇我们将在商城中添加SkyWalking构建调用链监控. 顺带一下怎么把ES设置为Windows服务,cd到ES的bin文件夹,运行ela ...

  5. Spring Cloud Alibaba 实战(十三) - Sleuth调用链监控

    本文概要:大白话剖析调用链监控原理,然后学习Sleuth,Zipkin,然后将Sleuth整合Zipkin,最后学习Zipkin数据持久化(Elasticsearch)以及Zipkin依赖关系图 实战 ...

  6. dubbo+zipkin调用链监控

    分布式环境下,对于线上出现问题往往比单体应用要复杂的多,原因是前端的一个请求可能对应后端多个系统的多个请求,错综复杂. 对于快速问题定位,我们一般希望是这样的: 从下到下关键节点的日志,入参,出差,异 ...

  7. 大众美团服务链监控CAT

    github链接:https://github.com/dianping/cat CAT 作为服务端项目基础组件,提供了 Java, C/C++, Node.js, Python, Go 等多语言客户 ...

  8. springboot 项目添加jaeger调用链监控

    1.添加maven依赖<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId&g ...

  9. 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链

    买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...

随机推荐

  1. 为啥程序会有bug?

    如果这是第二次看到我的文章,欢迎右侧扫码订阅我哟~ 

  2. [翻译 EF Core in Action 2.3] 理解EF Core数据库查询

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  3. 为什么面试你要25K,HR只给你20K?

    周末了,我们来聊个轻松的话题,关于涨薪,哈哈~ 前阵子,栈长给大家分享了<为什么公司宁愿 25K 重新招人,也不给你加到 20K?>,今天我们来聊一个差不多的话题: 为什么面试你要25K, ...

  4. [翻译 EF Core in Action 1.10] 应该在项目中使用EF Core吗?

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  5. aps .net MVC单用户登录

    当不允许多用户同时登录一个帐号时,就需要一种机制,当再登录一个相同的帐号时,前面登录的人被挤下线. 原文地址:http://www.cnblogs.com/f23wangj/p/4984302.htm ...

  6. webapi 跨域问题

    参考:http://www.cnblogs.com/chenxizhang/p/3821703.html 给自己做个笔记 HttpContext.Current.Response.AddHeader( ...

  7. C#删除字符串最后一个字符

    例:字符串 string str="2,3,5,7,9," 去掉最后一个逗号 ","; 常用的方法: 1.SubString()方法 str=str.SubSt ...

  8. String字符串类总结

    object类 int hashCode() Object定义的hashCode方法能为不同对象返回不同的整数.实际上是把JVM给对象分配的地址转化为整数,确保了逻辑上的唯一性.而转化的散列算法,可能 ...

  9. 海思Hi3559A/CV100 DDR4驱动配置手册

    Hi3559AV100 DDR4 驱动配置说明 1.1 Hi3559AV100 DDR4 CLK/AC 驱动配置方法 寄存器地址 DDR PHY0:0x1206d0bc DDR PHY1:0x1206 ...

  10. 在Salesforce成长:需要好奇心

    今天的正题,今天谈谈好奇心和技术.这两天北大学霸Cherry分两次问了我两个问题,都触发了很好的结果和思考,让大家都受益. 第一天是她在做Salesforce和Flexible Report集成项目中 ...