我是反应式编程世界的新手,我正在尝试使用rxjava创建一个简单的背压感知消息处理。
以下是我想要实现的工作流程:
可以继续使用字符串流。
执行耗时的操作并将消息更改为另一个字符串
执行另一项耗时的操作。
现在我使用以下代码:
{
Flowable.create(subscriber -> {
some_stream.forEach(data -> {
subscriber.onNext(data);
});
}, BackpressureStrategy.BUFFER).
subscribeOn(Schedulers.io()). // Data emission will run io scheduler
observeOn(Schedulers.computation()). // Map operation will run on computation scheduler
map(val -> Time_Consuming_Task(val)). // Task returns another string
observeOn(Schedulers.io()). / Next consumer will run on computation scheduler
subscribe(val -> Another_Time_Consuming_Task(val));
}
现在对于小型操作,我没有看到任何与背压有关的问题。
但对于大流,我不知道它会如何表现。
现在我的问题是: -
BackpressureStrategy.BUFFER 时的默认缓冲区大小是什么?数据在哪里缓冲?
如果我想在每次耗费任务之前创建两个背压缓冲区,我应该使用 onBackpressureBuffer运算符怎么办?
如果缓冲区已满,我不想丢失数据,我想在这种情况下等待什么?
答案 0 :(得分:1)
这比之前的1024降低了(你可以看到在RxJava here中实现的更改)。还有一个系统属性,您可以根据需要自行调整它:
System.setProperty("rx.ring-buffer.size", "8");
因为它们被称为环形缓冲区,它们存储在内存中。您可以阅读有关他们的更多信息here。
循环缓冲区的结果是当它已满并执行后续写入时,它会开始覆盖最旧的数据。
引用wiki文章关于Circular buffer 。
当您知道rx.ring-buffer.size
时,您可以做的最好的事情就是使用RxJava 2中给出的以下API:
onBackpressureBuffer(int capacity, // This is the given bound, not a setter for the ring buffer
Action0 onOverflow, // The desired action to execute
BackpressureOverflow.Strategy strategy) // The desired strategy to use
同样,我不能说得更好,让我引用Backpressure (2.0)上的RxJava wiki:
BackpressureOverflow.Strategy实际上是一个接口,但是BackpressureOverflow类提供了4个静态字段,其实现代表了典型的操作:
ON_OVERFLOW_ERROR
:这是前两次重载的默认行为,表示BufferOverflowException- 相同
ON_OVERFLOW_DEFAULT
:目前与ON_OVERFLOW_ERRORON_OVERFLOW_DROP_LATEST
:如果发生溢出,将简单地忽略当前值,并且只有在下游请求时才会传递旧值。ON_OVERFLOW_DROP_OLDEST
:删除缓冲区中最旧的元素并将当前值添加到缓冲区中。请注意,最后两个策略会导致流不连续,因为它们会丢弃元素。此外,他们不会发出BufferOverflowException信号。
以下是一个例子:
Flowable.range(1, 1_000_000)
.onBackpressureBuffer(16, () -> { },
BufferOverflowStrategy.ON_OVERFLOW_DROP_OLDEST)
.observeOn(Schedulers.computation())
.subscribe(e -> { }, Throwable::printStackTrace);
值得注意的是:
RxJava 2.x中的
Observable
类型没有背压概念。实施Observable
与默认使用onBackpressureBuffer()
实际上相同。 UI事件,一次性网络请求和状态更改都应该使用此方法。Completable
,Maybe
和Single
类型也可以指示此行为。如果您需要支持背压,RxJava 2.x的新类
Flowable
与RxJava 1.x中的Observable
类似的背压感知。但是,更新后的库现在需要明确选择背压策略以防止出现意外MissingBackpressureExceptions
。
了解更多: