调用链监控 CAT 之 URL埋点实践
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埋点实践的更多相关文章
- 第四模块 :微服务调用链监控CAT架构和实践
采样率:每一个请求为都进行记录,或者100次请求为记录50次 各个开源框架都满足opentracing的标准,只要使用opentracing标准埋点的客户端,可以使用不同的客户端去展示,opentra ...
- 调用链监控 CAT 之 入门
简介 CAT 是一个实时和接近全量的监控系统,它侧重于对Java应用的监控,基本接入了美团上海所有核心应用.目前在中间件(MVC.RPC.数据库.缓存等)框架中得到广泛应用,为美团各业务线提供系统的性 ...
- dubbo+zipkin调用链监控(二)
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- .Net Core 商城微服务项目系列(十):使用SkyWalking构建调用链监控(2019-02-13 13:25)
SkyWalking的安装和简单使用已经在前面一篇介绍过了,本篇我们将在商城中添加SkyWalking构建调用链监控. 顺带一下怎么把ES设置为Windows服务,cd到ES的bin文件夹,运行ela ...
- Spring Cloud Alibaba 实战(十三) - Sleuth调用链监控
本文概要:大白话剖析调用链监控原理,然后学习Sleuth,Zipkin,然后将Sleuth整合Zipkin,最后学习Zipkin数据持久化(Elasticsearch)以及Zipkin依赖关系图 实战 ...
- dubbo+zipkin调用链监控
分布式环境下,对于线上出现问题往往比单体应用要复杂的多,原因是前端的一个请求可能对应后端多个系统的多个请求,错综复杂. 对于快速问题定位,我们一般希望是这样的: 从下到下关键节点的日志,入参,出差,异 ...
- 大众美团服务链监控CAT
github链接:https://github.com/dianping/cat CAT 作为服务端项目基础组件,提供了 Java, C/C++, Node.js, Python, Go 等多语言客户 ...
- springboot 项目添加jaeger调用链监控
1.添加maven依赖<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId&g ...
- 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链
买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...
随机推荐
- Python GIL(Global Interpreter Lock)
一,介绍 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native t ...
- 用 opencv和numpy进行图片和字符串互转,并保存至 json
用 opencv和numpy进行图片和字符串互转,并保存至 json 转至 https://zhuanlan.zhihu.com/p/27349847 受 用 base64 进行图片和字符串互转,并保 ...
- vue防止按钮在短时间内被多次点击的方法
vue组件 (function(){ let openDelay=false; Vue.directive('intervalclick', function(el,binding){ el.oncl ...
- 基于Webpack, KnockoutJs,esyui,koeasyui实现类vue-cli生成的模板框架
前后端分离的开发机制,基本上是开发现代业务系统的标配.可在国内某些特殊领域还是存在大量的以JQuery走天涯的现象,但其中也不泛有追求技术者,如不才的鄙人.不才的本人曾以JQuery走天涯:后又接受了 ...
- TensorFlow从1到2(六)结构化数据预处理和心脏病预测
结构化数据的预处理 前面所展示的一些示例已经很让人兴奋.但从总体看,数据类型还是比较单一的,比如图片,比如文本. 这个单一并非指数据的类型单一,而是指数据组成的每一部分,在模型中对于结果预测的影响基本 ...
- Netty源码—六、tiny、small内存分配
tiny内存分配 tiny内存分配流程: 如果申请的是tiny类型,会先从tiny缓存中尝试分配,如果缓存分配成功则返回 否则从tinySubpagePools中尝试分配 如果上面没有分配成功则使用a ...
- 第15章 时间常数字符串比较 - IdentityModel 中文文档(v1.0.0)
在比较安全上下文中的字符串(例如比较键)时,应尽量避免泄漏时序信息. 该TimeConstantComparer类可以帮助: var isEqual = TimeConstantComparer.Is ...
- C# 填充Excel图表、图例背景色
填充背景色,一般可以选择多种不同样式来填充背景,包括填充为纯色背景.渐变背景.图片背景或者纹理背景等.下面的内容将分别介绍通过C#来设置Excel中图表背景色.以及图表中的图例背景色的方法. 使用工具 ...
- MySQL5.7下面,误操作导致的drop table db1.tb1; 的恢复方法:
MySQL5.7下面,误操作导致的drop table db1.tb1; 的恢复方法: 0.停业务数据写入.[iptables封禁] 1.从备份服务器上拉取最新的一个全备文件,恢复到一个临时的服务器上 ...
- linux用curl发送post请求
1.curl -X POST “http://XXXXXXX”这种请求方式参数直接写在URL里面的,而不是body