背景

Stream大家应该都很熟悉了,java8中为所有的集合类都引入了Stream的概念。优雅的链式操作,流式处理逻辑,相信用过的人都会爱不释手。

每个数据流都有一个生产者一个消费者。生产者负责产生数据,而消费者负责消费数据。如果是同步系统,生产一个消费一个没什么问题。但是如果在异步系统中,就会产生问题。

因为生产者无法感知消费者的状态,不知道消费者到底是繁忙状态还是空闲状态,是否有能力去消费更多的数据。

一般来说数据队列的长度都是有限的,即使没有做限制,但是系统的内存也是有限的。当太多的数据没有被消费的话,会导致内存溢出或者数据得不到即使处理的问题。

这时候就需要back-pressure了。

如果消息接收方消息处理不过来,则可以通知消息发送方,告知其正在承受压力,需要降低负载。back-pressure是一种消息反馈机制,从而使系统得以优雅地响应负载, 而不是在负载下崩溃。

而reactive stream的目的就是用来管理异步服务的流数据交换,并能够让接收方自主决定接受数据的频率。back-pressure就是reactive stream中不可或缺的一部分。

更多内容请访问www.flydean.com

什么是reactive stream

上面我们讲到了reactive stream的作用,大家应该对reactive stream有了一个基本的了解。这里我们再给reactive stream做一个定义:

reactive stream就是一个异步stream处理的标准,它的特点就是非阻塞的back pressure。

reactive stream只是一个标准,它定义了实现非阻塞的back pressure的最小区间的接口,方法和协议。

所以reactive stream其实有很多种实现的,不仅仅是java可以使用reactive stream,其他的编程语言也可以。

reactive stream只是定义了最基本的功能,各大实现在实现了基本功能的同时可以自由扩展。

目前reactive stream最新的java版本是1.0.3,是在2019年8月23发布的。它包含了java API,协议定义文件,测试工具集合和具体的实现例子。

深入了解java版本的reactive stream

在介绍java版本的reactive stream之前,我们先回顾一下reactive stream需要做哪些事情:

  1. 能够处理无效数量的消息
  2. 消息处理是有顺序的
  3. 可以异步的在组件之间传递消息
  4. 一定是非阻塞和backpressure的

为了实现这4个功能,reactive stream定义了4个接口,Publisher,Subscriber,Subscription,Processor。这四个接口实际上是一个观察者模式的实现。接下来我们详细来分析一下各个接口的作用和约定。

Publisher

先看下Publisher的定义:

public interface Publisher<T> {
public void subscribe(Subscriber<? super T> s);
}

Publisher就是用来生成消息的。它定义了一个subscribe方法,传入一个Subscriber。这个方法用来将Publisher和Subscriber进行连接。

一个Publisher可以连接多个Subscriber。

每次调用subscribe建立连接,都会创建一个新的Subscription,Subscription和subscriber是一一对应的。

一个Subscriber只能够subscribe一次Publisher。

如果subscribe失败或者被拒绝,则会出发Subscriber.onError(Throwable)方法。

Subscriber

先看下Subscriber的定义:

public interface Subscriber<T> {
public void onSubscribe(Subscription s);
public void onNext(T t);
public void onError(Throwable t);
public void onComplete();
}

Subscriber就是消息的接收者。

在Publisher和Subscriber建立连接的时候会触发onSubscribe(Subscription s)方法。

当调用Subscription.request(long)方法时,onNext(T t)会被触发,根据request请求参数的大小,onNext会被触发一次或者多次。

在发生异常或者结束时会触发onError(Throwable t)或者onComplete()方法。

Subscription

先看下Subscription的定义:

public interface Subscription {
public void request(long n);
public void cancel();
}

Subscription代表着一对一的Subscriber和Publisher之间的Subscribe关系。

request(long n)意思是向publisher请求多少个events,这会触发Subscriber.onNext方法。

cancel()则是请求Publisher停止发送信息,并清除资源。

Processor

先看下Processor的定义:

public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}

Processor即是Subscriber又是Publisher,它代表着一种处理状态。

JDK中reactive stream的实现

在JDK中java.util.concurrent.Flow就是reactive stream语义的一种实现。

Flow从JDK9就开始有了。我们看下它的结构:

从上图我们可以看到在JDK中Flow是一个final class,而Subscriber,Publisher,Subscription,Processor都是它的内部类。

我们会在后面的文章中继续讲解JDK中Flow的使用。敬请期待。

总结

reactive stream的出现有效的解决了异步系统中的背压问题。只不过reactive stream只是一个接口标准或者说是一种协议,具体的实现还需要自己去实现。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/reactive-stream-protocol/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

reactive stream协议详解的更多相关文章

  1. RTMP协议详解(转)

    转自<RTMP协议详解(一) (二) (三) > Real Time Messaging Protocol(实时消息传送协议协议)是Adobe Systems公司为Flash播放器和服务器 ...

  2. zz:NETCONF协议详解

    随着SDN的大热,一个诞生了十年之久的协议焕发了第二春,它就是NETCONF协议.如果你在两年前去搜索NETCONF协议,基本得到的信息都是"这个协议是一个网管协议,主要目的是弥补SNMP协 ...

  3. HTTP协议详解(转)

    转自:http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx Author :Jeffrey 引言 HTTP是一个属于应用层的面向对象的 ...

  4. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

  5. HTTP协议详解

    Author :Jeffrey 引言 HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展. ...

  6. 动态选路、RIP协议&&OSPF协议详解

    动态选路.RIP协议&&OSPF协议详解 概念 当相邻路由器之间进行通信,以告知对方每个路由器当前所连接的网络,这时就出现了动态选路.路由器之间必须采用选路协议进行通信,这样的选路协议 ...

  7. ASP.NET知识总结(3.HTTP协议详解)

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  8. 接口测试之HTTP协议详解

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  9. 计算机网络(12)-----HTTP协议详解

    HTTP协议详解 http请求 http请求由三部分组成,分别是:请求行.消息报头.请求正文 (1)请求行 请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Metho ...

  10. OSPF协议详解

    CCNP OSPF协议详解 2010-02-24 20:30:22 标签:CCNP 职场 OSPF 休闲 OSPF(Open Shortest Path Fitst,ospf)开放最短路径优先协议,是 ...

随机推荐

  1. 【webserver 前置知识 01】Linux系统编程入门

    题外话,PA里面也有很不错的Linux基础基础 传送门:https://nju-projectn.github.io/ics-pa-gitbook/ics2019/linux.html 静态库与动态库 ...

  2. 【LeetCode哈希表#5】四数相加II(map)

    四数相加II 力扣题目链接(opens new window) 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + ...

  3. 在Ubuntu搭建DHCP服务器

    一.提供DHCP的服务器,自己必须有固定的IP地址 不然局域网就乱了,服务器自身启动(比如搭建完DHCP服务后,重新启动了服务器)的时候,DHCP服务器没有IP地址,无法和自己的DHCP服务通信. 在 ...

  4. C#的Winform程序关于单击和双击的区别 - 开源研究系列文章

    前些天编码的时候有个关于应用程序的托盘图标的鼠标Mouse Down里的单击和双击的问题,只是想单击的时候显示主窗体,双击的时候显示操作窗体.但是编码并调试的时候发现Windows的鼠标双击的事件先执 ...

  5. Java 设计模式----单例模式--饿汉式

    1 package com.bytezreo.singleton; 2 3 /** 4 * 5 * @Description 单例设计模式 例子-----饿汉式 6 * @author Bytezer ...

  6. Java 求数值型数组中的最大元素 最小值 平均值 总和等 要求:随机数是 两位数

    1 /* 2 * 3 * 算法考查:求数值型数组中的最大元素 最小值 平均值 总和等 4 * 要求:随机数是 两位数 5 * [10,99] 6 * 公式:(int)(Math.random()*(9 ...

  7. ConcurrentHashMap的put方法

    使用JDK8 源码: public V put(K key, V value) { return putVal(key, value, false); } /** Implementation for ...

  8. python AI应用开发编程实战 大模型实战基础(数据存储类型列表与字典)(二)

    大模型开发中,需要和自己的业务融合,我们要对自己的数据处理,熟悉外理excle  word  pdf 数据然后处理后可以放到向量数据库,或者直接Assistants API传到大模型引用,不管怎么样数 ...

  9. 借助 Terraform 功能协调部署 CI/CD 流水线-Part 2

    在第一部分的文章中,我们介绍了3个步骤,完成了教程的基础配置: 使用 Terraform 创建 AWS EKS Infra 在 EKS 集群上部署 ArgoCD 及其依赖项 设置 Bitbucket ...

  10. jQuery 框架

    jQuery 框架 目录 jQuery 框架 一. 概述 二. jQuery 安装引用 2.1 安装 2.2 本地导入使用 2.3 jQuery CDN引入 三. jQuery基本语法 四. 查找标签 ...