这个异步 HystrixCommand 有啥问题?

Posted

技术标签:

【中文标题】这个异步 HystrixCommand 有啥问题?【英文标题】:Whats wrong with this Async HystrixCommand?这个异步 HystrixCommand 有什么问题? 【发布时间】:2017-11-16 07:01:19 【问题描述】:

我需要不时发送通知,我异步执行此任务。我正在使用 HystrixCommand 如下执行异步 RestTemplate 调用,但该调用不起作用:

@HystrixCommand
    public Future<String> notify(final Query query) 
        return new AsyncResult<String>() 
            @Override
            public String invoke() 
                String result = null;
                try 
                    ResponseEntity<HashMap> restExchange = restTemplate.exchange(url,
                            HttpMethod.POST,
                            new HttpEntity<String>(mapper.writeValueAsString(queryMap), httpHeaders),
                            HashMap.class);
                    LOGGER.info("Response code from " + url + " = " + restExchange.getStatusCodeValue());
                    result = ""+ restExchange.getStatusCodeValue();
                 catch(Exception e) 
                    LOGGER.error("Exception while sending notification! Message = " + e.getMessage(), e);
                
                return result;
            
        ;
    

这是我之前尝试做的(也没有工作):

@HystrixCommand
    public String notify(final Query query) 
        new Thread(new Runnable() 
            @Override
            public void run() 

                try 
                    ResponseEntity<HashMap> restExchange = restTemplate.exchange(url, HttpMethod.POST,
                            new HttpEntity<String>(mapper.writeValueAsString(queryMap), httpHeaders), HashMap.class);
                    LOGGER.info("Response code from " + url + " = " + restExchange.getStatusCodeValue());

                 catch (Exception e) 
                    LOGGER.error("Exception while sending notification! Message = " + e.getMessage(), e);
                

            
        ).start();
      

P.S:在标签中添加 sleuth 的原因是,在新线程中执行此操作不会传播标头(baggage-*),因此尝试此操作希望 Hystrix 命令可以解决问题

【问题讨论】:

你能粘贴你最初尝试做的事情吗? 我觉得你可能用错了future,你不用显式执行吗?对Future没有太多经验,通常使用CompletableFuture。 @MarcinGrzejszczak 我将整个方法包装在一个可运行文件中,并就地调用 start() 。从来没有工作过,我将用早期的代码编辑问题,同时,你看到我可以做些什么来执行异步HystrixCommand,控件甚至没有进入invoke方法。 你知道它必须用TraceRunnable 包裹起来吗? 我还假设 RestTemplate 是一个 bean?这个例子是如此依赖于线程,以至于如果不调试它,我不能说太多。也许它与github.com/spring-cloud/spring-cloud-sleuth/issues/612有关? 【参考方案1】:

方法 notify 是从同一个类中的方法调用的吗?如果是这种情况,请尝试直接从另一个类调用方法 notify,其中 notify 方法的封闭类作为依赖项注入。

基本上,尝试这样做:

改为:

【讨论】:

【参考方案2】:

使用Runnable 时,您必须将它们包装在跟踪表示中。即TraceRunnable。它在文档中 - http://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html#_runnable_and_callable 。

至于为什么 Hystrix 的东西不起作用 - 很可能与 https://github.com/spring-cloud/spring-cloud-sleuth/issues/612 有关。

【讨论】:

@marcun 确认不是sleuth的问题,我从服务中去掉了sleuth依赖,还是控件没有进入AsyncResult的'invoke'方法。

以上是关于这个异步 HystrixCommand 有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

并发、并行和异步方法有啥区别?

阻塞与同步、非阻塞和异步有啥区别? [复制]

JavaScript 中的事件循环和 Node.js 中的异步非阻塞 I/O 有啥区别?

HTTP请求中同步与异步有啥不同

`|_| 和有啥区别?异步移动 ` 和 `异步移动 |_| `

异步任务有啥用? [关闭]