我的应用程序中的一种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;
答案 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();