拉的理解:由程序发起从数据源读取。
推的理解:由数据源往响应接口推送(通常也需要程序发起请求一次)。
背压控制:推与拉的混合。
纯拉示例(purepull):
逐个请求下一个元素会导致从服务传递请求到数据库上花费额外的时间。大部分时间用于等待。
结合批处理优化(batchedpull):
根据数量批处理拉,但是还是没有解决空闲等待的问题
推的方式(pushmodel)
public Observable<Item> list(int count) {
return dbClient.getStreamOfItems()
.filter(this::isValid)
.take(count);
}
第一个响应时会依然有一大段空闲时间,当第一个元素到达后,数据库会发送后续元素,整体时间变短。服务收集完元素,数据库会忽略剩下的。但是带来另一个流量控制的问题,
无论是无界队列还是有界队列,有界阻塞队列都不能完美解决。(纯推模式下加入批处理可以稳定生产速率,使性能提升,比如Kotlin的Flow.buffer)
解决方案 :背压
混合推拉模型:
请求新的数据不需要中断或阻塞正在进行的元素处理。转换纯推模型可以将request设置为Long.MAX_VALUE。
git add 无效,一不小心把示例代码删除了(不止推拉,还有好多),心碎!