响应式编程(一)

Reactive-Stream

Reactive Streams是JVM面向流的库的标准和规范

1、处理可能无限数量的元素

2、有序

3、在组件之间异步传递元素

4、强制性非阻塞背压模式

在Java中,常用的背压机制是响应式流编程中的反压(Reactive Streams Backpressure)。反压是一种生产者-消费者模型,其中消费者可以向生产者发出信号,告知其需要的数据量和承受的压力,生产者则据此进行相应的数据生产和传输。这种机制可以防止消费者被超过其处理能力的数据压倒,保持数据流的平衡。

响应式编程(一)_第1张图片

响应式编程(一)_第2张图片响应式编程(一)_第3张图片 

API Components:

  1. Publisher:发布者;产生数据流
  2. Subscriber:订阅者; 消费数据流
  3. Subscription:订阅关系订阅关系是发布者和订阅者之间的关键接口。订阅者通过订阅来表示对发布者产生的数据的兴趣。订阅者可以请求一定数量的元素,也可以取消订阅。
  4. Processor:处理器; 处理器是同时实现了发布者和订阅者接口的组件。它可以接收来自一个发布者的数据,进行处理,并将结果发布给下一个订阅者。处理器在Reactor中充当中间环节,代表一个处理阶段,允许你在数据流中进行转换、过滤和其他操作。 

 响应式编程(一)_第4张图片响应式编程(一)_第5张图片响应式编程(一)_第6张图片

public class FlowDemo {
    // 发布订阅模型
    public static void main(String[] args) throws InterruptedException {
        //1.定义一个发布者,发布数据
        SubmissionPublisher publisher = new SubmissionPublisher<>();
        for (int i = 0; i < 10; i++) {
            publisher.submit("p-" + i);
        }
        //2.定义一个订阅者,订阅者感兴趣发布者的数据
        Flow.Subscriber subscriber = new Flow.Subscriber() {
            private Flow.Subscription subscription;

            @Override //在订阅时,执行这个回调
            public void onSubscribe(Flow.Subscription subscription) {
                System.out.println(Thread.currentThread() + "订阅开始了:" + subscription);
                this.subscription = subscription;
                //从上游请求一个数据,根据数据处理能力自设置
                subscription.request(1);
                //请求所有数据
//                subscription.request(Integer.MAX_VALUE);
            }

            @Override//在下一个元素到达时
            public void onNext(String item) {
                if (item.equals("p-6")) {
                    subscription.cancel();
                }
                System.out.println(Thread.currentThread() + "订阅者,接收到信息:" + item);
                //进行执行下一条,根据数据处理能力自设置
                subscription.request(1);
            }

            @Override
            public void onError(Throwable throwable) {
                System.out.println(Thread.currentThread() + "订阅者,接收到错误信号:" + subscription);
            }

            @Override
            public void onComplete() {
                System.out.println(Thread.currentThread() + "订阅者,接收到完成信号:" + subscription);
            }
        };
        //绑定发布者和订阅者
        publisher.subscribe(subscriber);
        for (int i = 0; i < 10; i++) {
                publisher.submit("p-" + i);
        }
        //不让主线程停止执行
        Thread.sleep(20000);
    }
}

订阅数据的线程与发布数据的线程不一致,jvm对于整个发布订阅关系已经做好了异步+缓存区处理=响应式系统

在代码内添加中间操作如下: 

public class FlowDemo {
    //定义流中间处理操作,只用写订阅者的接口
    static class MyProcessor extends SubmissionPublisher implements Flow.Processor {

        private Flow.Subscription subscription;

        @Override
        public void onSubscribe(Flow.Subscription subscription) {
            System.out.println("processor订阅绑定完成");
            this.subscription = subscription;
            subscription.request(1);
        }

        @Override
        public void onNext(String item) {
            System.out.println("processor拿到数据:" + item);
            item += ":haha";
            submit(item);
            subscription.request(1);
        }

        @Override
        public void onError(Throwable throwable) {

        }

        @Override
        public void onComplete() {

        }
    }

    // 发布订阅模型
    public static void main(String[] args) throws InterruptedException {
        //1.定义一个发布者,发布数据
        SubmissionPublisher publisher = new SubmissionPublisher<>();
        for (int i = 0; i < 10; i++) {
            publisher.submit("p-" + i);
        }
        //定义一个中间操作,给每个元素添加哈哈元素
        MyProcessor myProcessor = new MyProcessor();
        //2.定义一个订阅者,订阅者感兴趣发布者的数据
        Flow.Subscriber subscriber = new Flow.Subscriber() {
            private Flow.Subscription subscription;

            @Override //在订阅时,执行这个回调
            public void onSubscribe(Flow.Subscription subscription) {
                System.out.println(Thread.currentThread() + "订阅开始了:" + subscription);
                this.subscription = subscription;
                //从上游请求一个数据,根据数据处理能力自设置
                subscription.request(1);
                //请求所有数据
//                subscription.request(Integer.MAX_VALUE);
            }

            @Override//在下一个元素到达时
            public void onNext(String item) {
                if (item.equals("p-6")) {
                    subscription.cancel();
                }
                System.out.println(Thread.currentThread() + "订阅者,接收到信息:" + item);
                //进行执行下一条,根据数据处理能力自设置
                subscription.request(1);
            }

            @Override
            public void onError(Throwable throwable) {
                System.out.println(Thread.currentThread() + "订阅者,接收到错误信号:" + subscription);
            }

            @Override
            public void onComplete() {
                System.out.println(Thread.currentThread() + "订阅者,接收到完成信号:" + subscription);
            }
        };
        //绑定发布者和订阅者
        publisher.subscribe(myProcessor);
        myProcessor.subscribe(subscriber);
        for (int i = 0; i < 10; i++) {
            publisher.submit("p-" + i);
        }
        //不让主线程停止执行
        Thread.sleep(20000);
    }
}

响应式编程: 

1、底层:基于数据缓冲队列 + 消息驱动模型 + 异步回调机制

2、编码:流式编程 + 链式调用 + 声明式API

3、效果:优雅全异步 + 消息实时处理 + 高吞吐量 + 占用少量资源

Reactor

1、快速上手

介绍

Reactor 是一个用于JVM的完全非阻塞的响应式编程框架,具备高效的需求管理(即对 “背压(backpressure)”的控制)能力。它提供了异步序列 API Flux(用于[N]个元素)和 Mono(用于 [0|1]个元素),并完全遵循和实现了“响应式扩展规范”。

Reactor 的 reactor-ipc 组件还支持非阻塞的进程间通信(inter-process communication, IPC)。 Reactor IPC 为 HTTP(包括 Websockets)、TCP 和 UDP 提供了支持背压的网络引擎,从而适合 应用于微服务架构。并且完整支持响应式编解码。

依赖

 
    
        
            io.projectreactor
            reactor-bom
            2023.0.0
            pom
            import
        
    

    
        &

你可能感兴趣的:(java)