坑:异步调用其他服务避免使用AsyncRestTemplate

现象

订单服务的几个流程推动接口,出现了大量异常。持续20分钟。

排查

初步查看日志,发现这段时间有大量异常抛出,全部都是

java.lang.IllegalStateException: No instances available for travel-push。如图:

比较奇怪的是push全都是异步调用的。按理说不能影响到主流程才对。

查代码发现,用的异步调用,是用的org.springframework.web.client.AsyncRestTemplate

AsyncRestTemplate这个还是标注成废弃的

AsyncRestTemplate处理异步层面比较靠近调用,所以当被调用服务不可达的时候,这里会抛出异常,还是挺危险的。

并且这种方式不能传递traceId。

结论

可以自己写异步替代AsyncRestTemplate,利用CompletableFuture显式处理成功和失败。

同时可以指定executor来传递traceId。详见 异步线程带上traceId

附:异步线程带上traceId

我们在做异步处理的时候。用logger打日志以及http跨模块调用时,traceId都会因为线程改变而丢失原来的跟踪信息。在排查问题看日志时很不方便。

traceId其实是腾讯tsf基于spring cloud sleuth搞的,是trace和span中trace的id。

在其官方文档中,提供了几种异步传递trace/span的机制。

原地址:Spring Cloud Sleuth

举个例子,

我们比较常用的是通过executor去创建一个异步线程,可以用LazyTraceExecutor去包装这个executor即可。

首先根据需要的场景,指定线程数等参数配置一个executor的bean。

@Bean(name = "myExecutorService")

public Executor getMyExecutorService() {

    BasicThreadFactory threadFactory = new BasicThreadFactory.Builder()

            .namingPattern("shunfeng-pool-%d")

            .daemon(true)

            .build();



    ThreadPoolExecutor threadPoolExecutor =

            new ThreadPoolExecutor(threadPoolConfig.getCorePoolSize(),

                    threadPoolConfig.getMaxPoolSize(),

                    threadPoolConfig.getKeepAliveSeconds(),

                    TimeUnit.SECONDS,

                    new LinkedBlockingQueue<>(1024),

                    threadFactory,

                    new ThreadPoolExecutor.AbortPolicy());



    return new LazyTraceExecutor(beanFactory, threadPoolExecutor);

}

在需要的地方注入,然后按原来的方式使用即可。

@Autowired

@Qualifier("myExecutorService")

Executor executor;





private void asyncDoSomething1() {

    log.info("async.");

    CompletableFuture.runAsync(() -> doSomething(), executor);

}



private void asyncDoSomething2() {

    log.info("async.");

    executor.execute(() -> doSomething());

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值