如何延迟RxJava中的可观察发射

时间:2016-07-02 20:00:14

标签: rx-java haproxy microservices

我们拥有微服务架构,我们通过网络进行服务间呼叫。 我们在顶级服务中使用RxJava,这导致创建对底层服务的大量并行请求。 因此我得到了#34;没有路由到主机错误"或"连接错误"。 为此,我想减慢RxJava Observable的排放,以便在创建新连接之前关闭先前的连接。 以下是示例代码:

    package com.demo.rxjava.rxjaxa.creation;
    import rx.Observable;
    import rx.Subscriber;
    import rx.schedulers.Schedulers;

    public class Delay {

        public static void main(String[] args) throws InterruptedException {
            Observable.just(1, 2, 3, 4, 5).subscribeOn(Schedulers.io())
                    .flatMap(integer -> {
                        return function1(integer);
                    }).observeOn(Schedulers.io())
                    .subscribe(new Subscriber<String>() {
                        @Override
                        public void onNext(String item) {
                            System.out.println("Next: " + item);
                        }

                        @Override
                        public void onError(Throwable error) {
                            System.err.println("Error: " + error.getMessage());
                        }

                        @Override
                        public void onCompleted() {
                            System.out.println("Sequence complete.");
                        }
                    });
        }

     public Observable<String> function1(String id) {
                // This is where we make network call
                Observable<Response> response = Rx.newClient(RxObservableInvoker.class)
                        .target("http://example.com/resource")
                        .request()
                        .queryParam("id", id)
                        .rx()
                        .get();
                response.obserOn(Schedulers.from(threadExecutor)).flatMap(response->{
                    return response.extractResponse();
                });
   }
}

2 个答案:

答案 0 :(得分:0)

为了延迟特定步骤,您可以使用zip并将第一个Observable.from中发出的每个项目合并为X时间间隔。

   /**
 * If we want to delay the every single item emitted in the pipeline we will need a hack,
 * one possible hack is use zip operator and combine every item emitted with an interval so every item emitted has to wait until interval emit the item.
 */
@Test
public void delay() {
    long start = System.currentTimeMillis();
    Subscription subscription = Observable.zip(Observable.from(Arrays.asList(1, 2, 3)), Observable.interval(200, TimeUnit.MILLISECONDS), (i, t) -> i)
                                          .subscribe(n -> System.out.println("time:" + (System.currentTimeMillis() - start)));
    new TestSubscriber((Observer) subscription).awaitTerminalEvent(3000, TimeUnit.MILLISECONDS);
}

这将打印

   time:537
   time:738
   time:936

此处更多实例示例https://github.com/politrons/reactive

答案 1 :(得分:0)

您应该在限制并行活动的Scheduler上发出对底层服务的请求,而不是延迟您的请求。例如:

 int maxParallel = 4;
 Scheduler scheduler = Schedulers.from(
     Executors.newFixedThreadPool(maxParallel));
 ...
 observable
   .flatMap(x -> 
       submitToBottomService(x)
         .subscribeOn(scheduler))
   .subscribe(subscriber);

顺便提一下你关闭连接。 Observable.using运算符用于关闭响应上下文中的资源(它在终止和取消订阅时关闭资源)。如果您还没有使用它,那就试试吧。