如何修复“ MissingBackpressureException”

时间:2019-05-14 23:36:45

标签: java rx-java rx-java2

我通过订阅PublishSubject的事件流来使用RxJava2 Flowables,它正在企业级应用程序中使用,我们没有选择删除任何事件。 我正在使用版本RxJava 2.2.8

我正在使用BackpressureStrategy.BUFFER,因为我不想丢失任何事件。

此外,我再次缓冲50000或3分钟,以较早者为准。我要做的就是合并事件,然后对其进行处理。

但是在跑步的几分钟后,我得到以下错误

io.reactivex.exceptions.MissingBackpressureException: Could not emit buffer due to lack of requests
at io.reactivex.internal.subscribers.QueueDrainSubscriber.fastPathOrderedEmitMax(QueueDrainSubscriber.java:121)
at io.reactivex.internal.operators.flowable.FlowableBufferTimed$BufferExactBoundedSubscriber.run(FlowableBufferTimed.java:569)
at io.reactivex.Scheduler$Worker$PeriodicTask.run(Scheduler.java:479)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)

我尝试通过设置来增加缓冲区的大小,但是行为没有变化。

System.setProperty("rx2.buffer-size", "524288");

另外,如果我缓冲更长的时间而不是3分钟,那么经过更长的时间后就会出现异常,这可能是因为当事件合并得更多时,我的下游性能会更好。但是,我没有选择的余地,因为这些都是实时活动,需要立即处理(3-5分钟)。

在发生错误的情况下,我在调用“ subscription.next”之前也尝试过thread.sleep(),但仍然得到相同的结果。

keySubject.hide()
.toFlowable(BackpressureStrategy.BUFFER)
.parallel()
.runOn(Schedulers.computation())
.map(e -> e.getContents())
.flatMap(s -> Flowable.fromIterable(s))
.sequential()
.buffer(3,TimeUnit.MINUTES,50000)
.subscribe(new Subscriber<List<String>>() {

@Override
  public void onSubscribe(Subscription var1) {
   innerSubscription = var1;
innerSubscription.request(1L);
 }

@Override
public void onNext(List<String> logs) {
    Subscription.request(1L);

///   Do some logic here

}

我想知道如何处理背压以避免这种异常?由于“ .buffer”方法而导致此异常吗? 有没有办法让我检查这些缓冲区的状态。同样,为什么即使我增加rx2.buffer-size,在相同的时间内仍会得到异常。理想情况下,如果出现异常是因为缓冲区已满,则系统应使用更长的缓冲区运行更长的时间。

关于此消息“由于缺少请求而无法发出缓冲区”的原因的任何帮助都是很好的。

1 个答案:

答案 0 :(得分:0)

问题是,为什么要使用不具备背压意识的主题?您是否将其用作可怜人的活动巴士?另外,假设e.getContents()是一个简单的方法,我相信您可以替换整个块

.toFlowable(BackpressureStrategy.BUFFER)
.parallel()
.runOn(Schedulers.computation())
.map(e -> e.getContents())
.flatMap(s -> Flowable.fromIterable(s))
.sequential()
.buffer(3,TimeUnit.MINUTES,50000)
.subscribe(new Subscriber<List<String>>() { ... });

.flatMapIterable(e -> e.getContents())
.buffer(3,TimeUnit.MINUTES,50000)
.rebatchRequests(1)
.observeOn(Schedulers.computation())
.doOnNext(s -> /* Do some logic here */)
.subscribe();