如何并行执行Hystrix命令?

时间:2018-01-09 13:28:24

标签: java hystrix

我的应用程序中的一种Spring服务方法向另外两个微服务发出请求。我想使用Hystrix做出这些请求以使其具有容错能力,并且我想并行运行它们。

到目前为止,我为每次调用实现了HystrixObservableCommand,并使用CountDownLatch等待两个命令完成(或失败)。

目前的解决方案看起来非常冗长。是否可以使用Observable功能并行执行Hystrix命令?

所需的解决方案看起来像是伪代码:

[Annotation]

不幸的是,这个理想的解决方案不起作用,因为Hystrix命令永远不会被执行。

我目前的解决方案是:

new LoadCustomerObservableCommand(customerClient, customerId).toObservable()
    .doOnError(throwable -> log.error("Failed to retrieve customer {} information for the reservation {}", customerId, reservationId, throwable))
    .doOnNext(customer -> myResponse.setCustomer(customer));

new GetTicketsObservableCommand(ticketsClient, reservationId).toObservable()
    .doOnError(throwable -> log.error("Failed to retrieve tickets for the reservation {}", reservationId, throwable))
    .doOnNext(tickets -> myResponse.setTickets(tickets));

final AtomicBoolean subRequestsFailed = new AtomicBoolean(false);

Observable.zip(customerObservable, ticketsObservable, (customer, tickets) -> null)
    .doOnError(throwable -> subRequestsFailed.set(true))
    .toBlocking()
    .first();

if (subRequestsFailed.get()) {
     throw new HystrixBadRequestException("One or more requests to submodules have been failed");
}

return dto;

2 个答案:

答案 0 :(得分:1)

使用zip组合器时,您对所需的解决方案有正确的想法。在该解决方案中未执行Hystrix命令的原因是生成的Observable没有订户。来自documentation

  

toObservable() - 返回一个“冷”Observable,在订阅生成的Observable之前不会订阅底层的Observable

只需在合并的Observable上调用subscribe()方法:

Observable.zip(customerObservable, ticketsObservable, (customer, tickets) -> null)
          .take(1)
          .doOnError(throwable -> subRequestsFailed.set(true))
          .subscribe();

答案 1 :(得分:0)

经过一番挖掘,我找到了解决方案。我的代码中错过的操作是“ subscribeOn”:

ResponseDTO result = Observable.zip(
            saleChannelPaxInventoryClient.getAvailabilities(saleChannel, routeLeg, date).subscribeOn(Schedulers.io()),
            saleChannelCarDeckInventoryClient.getAvailabilities(saleChannel, routeLeg, date).subscribeOn(Schedulers.io()),
            (paxAvailabilities, carDeckAvailabilities) -> {
               ResponseDTO out = new ResponseDTO();
               // process results of both observables here

               return out;
            }
    )
.toBlocking()
.single();
相关问题