写点什么

CAT 中实现异步请求的调用链查看

作者:Java高工P7
  • 2021 年 11 月 10 日
  • 本文字数:1591 字

    阅读完需:约 5 分钟

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


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)


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


;


}


@Override


public 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 {


//调用获取商品详细信息的 API

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
CAT中实现异步请求的调用链查看