My API成对地向两个独立的服务进行大约100次下游呼叫。在我将回复发送给客户之前,需要汇总所有回复。我使用hystrix-feign来进行HTTP调用。
我想出了一个优雅的解决方案,直到rxJava docs我发现了以下内容
BlockingObservable是一种提供阻塞运算符的Observable。它可用于测试和演示目的,但通常不适合生产应用程序(如果您认为需要使用BlockingObservable,这通常表明您应该重新考虑您的设计)。
我的代码大致如下
List<Observable<C>> observables = new ArrayList<>();
for (RequestPair request : requests) {
Observable<C> zipped = Observable.zip(
feignClientA.sendRequest(request.A()),
feignClientB.sendRequest(request.B()),
(a, b) -> new C(a,b));
observables.add(zipped);
}
Collection<D> apiResponse = = new ConcurrentLinkedQueue<>();
Observable
.merge(observables)
.toBlocking()
.forEach(combinedResponse -> apiResponse.add(doSomeWork(combinedResponse)));
return apiResponse;
基于此设置的几个问题:
答案 0 :(得分:1)
更好的选择是返回其他运算符要使用的Observable
,但是您可能会使用阻塞代码(但它应该在后台线程上运行。)
public Observable<D> getAll(Iterable<RequestPair> requests) {
return Observable.from(requests)
.flatMap(request ->
Observable.zip(
feignClientA.sendRequest(request.A()),
feignClientB.sendRequest(request.B()),
(a, b) -> new C(a,b)
)
, 8) // maximum concurrent HTTP requests
.map(both -> doSomeWork(both));
}
// for legacy users of the API
public Collection<D> getAllBlocking(Iterable<RequestPair> requests) {
return getAll(requests)
.toList()
.toBlocking()
.first();
}
我是否理解在主线程到达forEach()之后才会进行实际的HTTP调用
是的,forEach
会触发整个操作序列。
我已经看到forEach()块中的代码由不同的线程执行,但是我无法验证forEach()块中是否可以有多个线程。那里的执行是并发的吗?
一次只允许一个线程在forEach
中执行lambda,但你可能确实看到不同的线程进入那里。