调用链监控 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调用链
买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...
随机推荐
- django 的时区设置
在Django的配置文件settings.py中,有两个配置参数是跟时间与时区有关的,分别是TIME_ZONE和USE_TZ 如果USE_TZ设置为True时,Django会使用系统默认设置的时区,即 ...
- WebGL学习之纹理贴图
为了使图形能获得接近于真实物体的材质效果,一般会使用贴图,贴图类型主要包括两种:漫反射贴图和镜面高光贴图.其中漫反射贴图可以同时实现漫反射光和环境光的效果. 实际效果请看demo:纹理贴图 2D纹理 ...
- Java的序列化和反序列化
概述 Java对象的序列化和反序列化,这个词对我来说追溯到大学阶段,学Java对象流时知道有这东西.老师告诉我们可以把Java对象化作字节流,储存文件或网络通信.然后就是巴啦巴拉,一脸懵逼.举个例子, ...
- 零基础怎么学java
首先告诉你的是,作为一个初学者想转行学习Java并不是很容易,Java本身是具有一定难度的,虽然说兴趣这东西可以让我们学习不累,但是有多少人学习是因为兴趣,或者有多少人知道自己的兴趣在哪?所以我很明确 ...
- python导出zabbix数据并发邮件脚本
Zabbix没有报表导出的功能,于是通过编写脚本导出zabbix数据并发邮件.效果如下: 下面是脚本,可根据自己的具体情况修改: #!/usr/bin/python #coding:utf-8 imp ...
- asp.net core系列 54 IS4用客户端凭据保护API
一. 概述 本篇开始进入IS4实战学习,从第一个示例开始,该示例是 “使用客户端凭据保护API”,这是使用IdentityServer保护api的最基本场景.该示例涉及到三个项目包括:Identity ...
- Python爬虫入门教程 62-100 30岁了,想找点文献提高自己,还被反爬了,Python搞起,反爬第2篇
学术搜索 学习理论的知识少不了去检索文献,好多文献为你的实操提供了合理的支撑,我所在的大学内网默认是有知网账户的,非常NICE 今天要完成的网站是 http://ac.scmor.com/ Googl ...
- SpringBoot进阶教程(二十四)整合Redis
缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非 ...
- 【我们一起写框架】C#的AOP框架
前言 AOP,大家都是听过的,它是一种面向切面的设计模式. 不过AOP虽然是被称为设计模式,但我们应该很少能看到AOP设计的框架.为什么呢? 因为,AOP单独设计的框架几乎是无法使用的.普遍的情况是, ...
- PBFT概念与Go语言入门(Tendermint基础)
Tendermint作为当前最知名且实用的PBFT框架,网上资料并不很多,而实现Tendermint和以太坊的Go语言,由于相对小众,也存在资料匮乏和模糊错漏的问题.本文简单介绍PBFT概念和Go语言 ...