CAT中实现异步请求的调用链查看
CAT简介
CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统。美团点评基础架构部希望在基础存储、高性能通信、大规模在线访问、服务治理、实时监控、容器化及集群智能调度等领域提供业界领先的、统一的解决方案,CAT 目前在美团点评的产品定位是应用层的统一监控组件,在中间件(RPC、数据库、缓存、MQ 等)框架中得到广泛应用,为各业务线提供系统的性能指标、健康状况、实时告警等服务。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
准备工作
对于同步请求API,CAT服务端自然是可以看到的。同步请求API的实例可以参考之前的文章《五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链》。但对于异步请求API,因为不在同一线程中,在子线程中无法获取到父线程消息树,所以在CAT服务端是无法看到的对应请求。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
首先,写一个类实现Cat.Context接口,用于存放消息树的上下文信息:
public class CatContext implements Cat.Context {
private Map<String, String> properties = new HashMap<>();
@Override
public void addProperty(String key, String value) {
properties.put(key, value);
}
@Override
public String getProperty(String key) {
return properties.get(key);
}
@Override
public 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);
}
@Override
public V call() throws Exception {
//保存父线程消息树的上下文信息到子线程
ContextWarehouse.setContext(this.catContext);
return callable.call();
}
}
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
定义一些常量,在调用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;
}
}
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
异步请求实例
下面写一个异步请求的实例,通过多个商品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 {
//调用获取商品详细信息的API
return 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报表中就可以查看到异步请求了。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
CAT中实现异步请求的调用链查看的更多相关文章
- Springmvc中 同步/异步请求参数的传递以及数据的返回
转载:http://blog.csdn.net/qh_java/article/details/44802287 注意: 这里的返回就是返回到jsp页面 **** controller接收前台数据的方 ...
- springmvc中同步/异步请求参数的传递以及数据的返回
注意: 这里的返回就是返回到jsp页面 **** controller接收前台数据的方式,以及将处理后的model 传向前台***** 1.前台传递数据的接受:传的属性名和javabean的属性相同 ...
- iOS中POST异步请求
POST异步请求(代理) 1.遵循<NSURLConnectionDataDelegate> @interface ViewController ()<NSURLConnection ...
- Jquery中Ajax异步请求中的async参数的作用
之前不知道这个参数的作用,上网找了前辈的博客,在此收录到自己的博客,希望能帮到更多的朋友: test.html <a href="javascript:void(0)" on ...
- for循环中嵌套异步请求问题
for循环中嵌套了异步请求会导致顺序错乱,用递归代替for循环,可以保证正常执行顺序:
- vue 中promise 异步请求数据
export function getTypes(type) { return listDictItems({ code: type }).then((res) => { if (res.cod ...
- 在Mvc中进行异步请求是出现(没有为该对象定义无参数的构造函数)
解决办法就是给相应的类添加无参数的构造函数:
- 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链
买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...
- 异步请求中jetty处理ServletRequestListener的坑
标题起得比较诡异,其实并不是坑,而是jetty似乎压根就没做对异步request的ServletRequestListener的特殊处理,如果文中有错误欢迎提出,可能自己有所疏漏了. 之前遇到了一个b ...
随机推荐
- 208道Java常见的面试题
一.Java 基础 1.JDK 和 JRE 有什么区别? JRE=JVM+各种基础类库+java类库(String\System) JDK>JRE>JVM JRE:是java运行时环境 ...
- Dubbo 高级特性实践-泛化调用
引言 当后端Java服务用Dubbo协议作为RPC方案的基础,但部分消费方是前端Restful的PHP服务,不能直接调用,于是在中间架设了Router服务提供统一的基于HTTP的后端调用入口. 而Ro ...
- 4.kafka API producer
1.Producer流程首先构建待发送的消息对象ProducerRecord,然后调用KafkaProducer.send方法进行发送.KafkaProducer接收到消息后首先对其进行序列化,然后结 ...
- c# 常见文件夹操作
- websocket之简易聊天室
一,带昵称的群聊 #!/usr/bin/env python # -*- coding:utf8 -*- import json from flask import Flask, request, r ...
- C++ 谓词(predicate) 与 仿函数 ( functor (function object))
谓词与函数对象 谓词 predicate C++ 标准定义谓词如下: The Predicate parameter is used whenever an algorithm expects a f ...
- Jmeter 中正则表达式提取器Regular Expression Extractor
正则表达式提取器点击后置处理器中Post Processors 中的正则表达式提取器 Regular Expression Extractor Appy to: 表示作用于哪一个请求Main samp ...
- Spring4- 04-Spring简易整合Mybatis -导入jar包/ 正常编写pojo/ 编写spring 配置文件
笔记要点&出错分析与总结 POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,工程组织 (AirportService为机场 ...
- CH6302 雨天的尾巴
6302 雨天的尾巴 0x60「图论」例题 背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了 ...
- JanusGraph 创建索引步骤(composite index)踩坑总结
前言 JanusGraph是一个图数据库引擎,安装及入门可以参考 JanusGraph 图数据库安装小记.为了提高查询速度,在使用过程中一般要为某些属性创建索引.这篇随笔主要是记录创建索引过程中踩过的 ...