CAT简介

CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统。美团点评基础架构部希望在基础存储、高性能通信、大规模在线访问、服务治理、实时监控、容器化及集群智能调度等领域提供业界领先的、统一的解决方案,CAT 目前在美团点评的产品定位是应用层的统一监控组件,在中间件(RPC、数据库、缓存、MQ 等)框架中得到广泛应用,为各业务线提供系统的性能指标、健康状况、实时告警等服务。

准备工作

对于同步请求API,CAT服务端自然是可以看到的。同步请求API的实例可以参考之前的文章《五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链》。但对于异步请求API,因为不在同一线程中,在子线程中无法获取到父线程消息树,所以在CAT服务端是无法看到的对应请求。

首先,写一个类实现Cat.Context接口,用于存放消息树的上下文信息:

public class CatContext implements Cat.Context {private Map<String, String> properties = new HashMap<>();@Overridepublic void addProperty(String key, String value) {properties.put(key, value);}@Overridepublic String getProperty(String key) {return properties.get(key);}@Overridepublic String toString() {return "CatContext{"+ "properties=" + properties + '}';}
}

我们可以先父线程消息树的上下文信息保存下来,然后在子线程使用。先写一个存放上下文信息的地方:

public class ContextWarehouse {private static ThreadLocal<CatContext> contextThreadLocal = new ThreadLocal();public static void setContext(final CatContext context) {contextThreadLocal.set(context);}public static CatContext getContext() {//先从ContextWarehouse中获取上下文信息CatContext context = contextThreadLocal.get();if (context == null) {context = new CatContext();Cat.logRemoteCallClient(context);}return context;}
}

实现Callable接口,创建一个自定义的类,实现了在子线程中存放父线程的上下文信息的功能:

public class OneMoreCallable<V> implements Callable<V> {private CatContext catContext;private Callable<V> callable;public DdCallable(final Callable<V> callable) {this.callable = callable;this.catContext = new CatContext();//获取父线程消息树的上下文信息Cat.logRemoteCallClient(this.catContext);}@Overridepublic V call() throws Exception {//保存父线程消息树的上下文信息到子线程ContextWarehouse.setContext(this.catContext);return callable.call();}
}

定义一些常量,在调用API时作为header中的key:

public class CatHttpConstants {public static final String CAT_HTTP_HEADER_CHILD_MESSAGE_ID = "DD-CAT-CHILD-MESSAGE-ID";public static final String CAT_HTTP_HEADER_PARENT_MESSAGE_ID = "DD-CAT-PARENT-MESSAGE-ID";public static final String CAT_HTTP_HEADER_ROOT_MESSAGE_ID = "DD-CAT-ROOT-MESSAGE-ID";
}

埋点时,在调用API的HttpClient工具类中统一增加代码,以GET方式为例:

public class HttpClientUtil {public static String doGet(String url) throws IOException {HttpGet httpGet = new HttpGet(url);CloseableHttpResponse response = null;CloseableHttpClient httpClient = HttpClientBuilder.create().build();String content = null;Transaction t = Cat.newTransaction(CatConstants.TYPE_CALL, url);try {CatContext context = ContextWarehouse.getContext();httpGet.setHeader(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID, context.getProperty(Cat.Context.ROOT));httpGet.setHeader(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID, context.getProperty(Cat.Context.PARENT));httpGet.setHeader(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID, context.getProperty(Cat.Context.CHILD));response = httpClient.execute(httpGet);if (response.getStatusLine().getStatusCode() == 200) {content = EntityUtils.toString(response.getEntity(), "UTF-8");t.setStatus(Transaction.SUCCESS);}} catch (Exception e) {Cat.logError(e);t.setStatus(e);throw e;} finally {if (response != null) {response.close();}if (httpClient != null) {httpClient.close();}t.complete();}return content;}
}

异步请求实例

下面写一个异步请求的实例,通过多个商品ID异步获取对应的商品详细信息:

public class ProductService {/*** 声明一个大小固定为10的线程池*/private static ExecutorService executor = Executors.newFixedThreadPool(10);/*** 通过商品ID列表异步获取对应的商品详细信息** @param productIds 商品ID列表* @return 对应的商品详细信息*/public List<String> findProductInfo(List<Long> productIds) {List<Future<String>> futures = new ArrayList<>();for (Long productId : productIds) {futures.add(executor.submit(new DdCallable(() -> {try {//调用获取商品详细信息的APIreturn HttpClientUtil.doGet("http://api.product/get?id=" + productId);} catch (Exception e) {return "";}})));}List<String> productInfos = new ArrayList<>();for (Future<String> future : futures) {try {//异步获取对应商品详细信息productInfos.add(future.get());} catch (Exception e) {productInfos.add("");}}return productInfos;}
}

这样写以后,在CAT服务端的Transaction报表中就可以查看到异步请求了。

CAT中实现异步请求的调用链查看相关推荐

  1. PHP guzzle异步请求数据,Guzzle中的异步请求

    Guzzle中的异步请求 使用Guzzle发起异步请求 Guzzle是一个PHP的HTTP客户端,它在发起http请求时不仅可以同步发起,还可以异步发起. $client = new Client() ...

  2. php中jquery ajax请求参数,浅谈Jquery中Ajax异步请求中的async参数的作用

    之前不知道这个参数的作用,上网找了前辈的博客,在此收录到自己的博客,希望能帮到更多的朋友: test.html asy.js function testAsync{ var temp; $.ajax( ...

  3. react中实现异步请求的方法一,react-thunk

    写在前面: 在react中,dispatch是同步执行reducers生成新状态的,对于页面的操作没有问题:但是如果点击事件是请求了某个结果,需要等待结果响应后再更新视图呢?应该如何处理?这里就用到了 ...

  4. SpringMVC中的异步请求-跨域访问

    发送异步请求: <%@page pageEncoding="UTF-8" language="java" contentType="text/h ...

  5. @async 没有异步_扒一扒VueCLI3.0中Axios异步请求同步化

    前台经常会遇到请求同步和异步的问题,今天咱们来聊一聊vue中同步请求和异步请求那些事儿. 说到接口的请求同步和异步问题,最早接触Ajax中就存在,Ajax传递的参数有一个async,默认情况下是fal ...

  6. html中的异步请求数据格式,解决layui中table异步数据请求不支持自定义返回数据格式的问题...

    使用版本 layui-v2.3.0 修改: 打开layui中table.js源码 在 Class.prototype.pullData 这个方法定义内部 //获得数据 Class.prototype. ...

  7. jax-rs jax-ws_在JAX-RS中处理异步请求中的超时

    jax-rs jax-ws JAX-RS 2.0在客户端和服务器端都支持异步编程范例. 这篇文章重点介绍了使用JAX-RS(2.0)API在服务器端执行异步REST请求时的超时功能 无需过多介绍,这里 ...

  8. 在JAX-RS中处理异步请求中的超时

    JAX-RS 2.0在客户端和服务器端都支持异步编程范例. 这篇文章重点介绍了使用JAX-RS(2.0)API在服务器端执行异步REST请求时的超时功能 无需过多介绍,这里是一个快速概述. 为了以异步 ...

  9. 异步请求中jetty处理ServletRequestListener的坑

    标题起得比较诡异,其实并不是坑,而是jetty似乎压根就没做对异步request的ServletRequestListener的特殊处理,如果文中有错误欢迎提出,可能自己有所疏漏了. 之前遇到了一个b ...

最新文章

  1. JSP第二次作业_5小题
  2. html5主要是针对哪方面行优化,前端知识点总结(HTML篇)
  3. YIFullScreenScroll
  4. 九种破解Xp登录密码方法
  5. [转载] 深入剖析 redis 主从复制
  6. 一些debug常用的魔法数值
  7. 调用cmd不显示黑框的方法
  8. 40.QT-QPropertyAnimationdong和QParallelAnimationGroup动画实现
  9. praying,blessing,wishing
  10. 《PostgreSQL 指南:内幕探索》之基础备份与时间点恢复(上)
  11. 95-40-014-生产者-KafkaProducer
  12. JSON-RPC轻量级远程调用协议介绍及使用
  13. java接口中有效的方法声明_在Java接口中,下列选顶中有效的方法声明是
  14. echarts 折线图y轴自定义 使用icon
  15. 【VS】错误1error LNK1168: 无法打开 F:\C++6\prob\ConsoleApplication1\Debug\ConsoleApplication1.exe 进行写入
  16. Python常用标准库、模块
  17. 数据结构算法—非递归算法求二叉树的叶子结点(C语言)
  18. css中自适应字体问题等
  19. 软件工程的完整生命周期
  20. 拆解1968年的美国军用电脑,真的怀疑是“穿越”啊!

热门文章

  1. 咻商跨境电商丨Shopee开店相关干货分享!
  2. 反转字符串java实现_反转字符串的几种实现(Java)
  3. Linux使用nmtui命令配置网卡(图形界面)
  4. 创建用户分类(基于聚类算法)
  5. 2.5G 传输特性分析仪 怎么选 TFN D300S 给您答案
  6. Python自定义模块:转换生成HTML表格
  7. 轮播图1/3样式轮播图,模仿淘宝详情页图片胶囊式轮播
  8. Shell文本处理编写单行指令的诀窍
  9. MySQL 将字符串转换为数字类型并进行排序
  10. 激光雷达角点检测 c语言,一种基于事件帧的角点检测方法与流程