Flowable

本文深入探讨了Flowable在异步数据传输过程中如何利用背压机制避免数据丢失及异常。详细介绍了BackpressureStrategy的不同选项及其对数据流的影响,特别关注BUFFER策略下缓存池的工作原理,以及如何通过e.requested()来监测并调整上游数据的发送。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> e)  {
                    for (int i = 1; i <= 1000000; i++) {
                        if(e.requested()==0)continue;
                        e.onNext(i);
                    }
                    e.onComplete();
            }
        }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {//响应式拉取数据
                        s.request(Long.MAX_VALUE);每次拉取数据的个数//不论设置多少上游缓存池初始值就是128 上游会一直发送数据直到发送完毕 // 但是我们设置必须要大于发射的数据值 才能保证数据全部接受完 所以设置大于上游数据值即可 暂时设置最大值
                        // s.request与发射器e.request不一样 代表获取缓存池的可使用数据
                        //下面是另一个大神测试出来的结果,我只是大概验证了一下
                     我们发现通过e.requested()获取到的上游当前未完成请求数量并不是一直递减的, 在递减到33时,又回升到了128.而回升的时机正好是在下游接收了96条数据之后。我们之前说过,异步缓存池中的数据并不是向下游发射一条便清理一条,而是每等累积到95条时, 清理一次。通过e.requested()获取到的值,正是在异步缓存池清理数据时,回升的。  也就是,异步缓存池每次清理后,有剩余的空间时,都会导致上游未完成请求数量的回升,这样既不会引发背压异常,也不会导致数据遗失。上游在发送数据的时候并不需要考虑下游需不需要,而只需要考虑异步缓存池中是否放得下,放得下便发,放不下便暂停。所以,通过e.requested()获取到的值,并不是下游真正的数据请求数量, 而是异步缓存池中可放入数据的数量。数据放入缓存池中后,再由缓存池按照下游的数据请求量向下传递,待到传递完的数据累积到95条之后, 将其清除,腾出空间存放新的数据。如果下游处理数据缓慢,则缓存池向下游传递数据的速度也相应变慢,进而没有传递完的数据可清除, 也就没有足够的空间存放新的数据,上游通过e.requested()获取的值也就变成了0, 如果此时,再发送数据的话,则会根据BackpressureStrategy背压策略的不同, 抛出MissingBackpressureException异常,或者丢掉这条数据。 所以上游只需要在e.requested()等于0时,暂停发射数据,便可解决背压问题。
                    }

                    @Override
                    public void onNext(Integer integer) {
                        try {
                            Thread.sleep(10*1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                       Log.e("TAG","接受"+integer + "个\n");

                    }

                    @Override
                    public void onError(Throwable t) {
                        Log.e("TAG",""+t.getMessage() + "\n");
                    }

                    @Override
                    public void onComplete() {

                    }
                });


    }
    //        ERROR, 抛出背压异常
//            BUFFER, //缓存池没有限制  直至oom  但是速率要满很多
//            DROP, 丢弃
//            LATEST 取最后一条数据必定放入缓存池
              MISSING  此策略表示,通过Create方法创建的Flowable没有指定背压策略,
              不会对通过OnNext发射的数据做缓存或丢弃处理,需要下游通过背压操作符
           (onBackpressureBuffer()/onBackpressureDrop()/onBackpressureLatest())指定背压策略
### Flowable 工作流引擎概述 Flowable 是一种开源的工作流和业务流程管理(BPM)平台,专注于 BPMN 2.0、CMMN 和 DMN 标准的支持。它为开发者提供了灵活且高性能的解决方案,用于构建复杂的企业级应用程序。Flowable 的设计目标是提供轻量级、可扩展和高效的框架,以满足现代企业对流程自动化的多样化需求[^4]。 以下是关于 Flowable 的一些关键特性和使用方法: 1. **核心组件** Flowable 包含多个模块,包括工作流引擎(Workflow Engine)、内容存储(Content Store)、表单引擎(Form Engine)、任务引擎(Task Engine)以及决策引擎(Decision Engine)。这些模块可以单独使用,也可以组合在一起形成完整的解决方案[^5]。 2. **BPMN 2.0 支持** Flowable 提供了对 BPMN 2.0 的全面支持,允许开发者通过图形化工具定义复杂的业务流程,并将其部署到 Flowable 引擎中执行。BPMN 2.0 是一种标准化的建模语言,广泛应用于业务流程的设计和实现[^6]。 3. **集成能力** Flowable 可以轻松地与 Spring 框架集成,支持基于注解的配置方式。此外,它还支持与 JPA、JTA 等技术栈的无缝协作,确保在分布式环境下的事务一致性[^7]。 4. **性能优化** Flowable 引擎经过高度优化,能够在高并发场景下保持稳定的性能表现。其内部采用了事件驱动架构和异步处理机制,从而显著提高了吞吐量和响应速度[^8]。 5. **REST API** Flowable 提供了一套完整的 REST API 接口,允许外部系统通过 HTTP 协议调用其功能。这使得开发者能够快速构建基于微服务架构的应用程序[^9]。 以下是一个简单的 Java 示例代码,展示如何启动 Flowable 引擎并运行一个流程实例: ```java import org.flowable.engine.ProcessEngine; import org.flowable.engine.ProcessEngines; import org.flowable.engine.RepositoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.runtime.ProcessInstance; public class FlowableExample { public static void main(String[] args) { // 初始化默认的 ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 获取 RepositoryService 用于部署流程定义 RepositoryService repositoryService = processEngine.getRepositoryService(); repositoryService.createDeployment() .addClasspathResource("processes/my-process.bpmn20.xml") .deploy(); // 获取 RuntimeService 用于启动流程实例 RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess"); System.out.println("流程实例已启动,ID: " + processInstance.getId()); } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值