浅谈RSocket与响应式编程
简介: RSocket是高效一个二进制的网络通讯协议,能够满足很多场景下使用。另外,RSocket也是一个激进的响应式捍卫者,激进到连API都跟响应式无缝集成。本文我们将和大家分享RSocket与响应式编程。
作者 | 素渡
来源 | 阿里技术公众号
一 RSocket的主要特性
首先,RSocket是高效一个二进制的网络通讯协议,能够满足很多场景下使用。其次,RSocket是一个激进的响应式捍卫者,激进到连API都跟响应式无缝集成。
1 四种通讯模式
即发即忘FireAndForget
立即发送一个请求,无需为这个请求发送响应报文。适用于监控埋点,日志上报等,这种场景下无需回执,丢失几个请求无伤大雅。
请求响应RequestResponse
请求方发送一条请求消息,响应方收到请求后并返回一条响应消息。传统的HTTP是典型的RequestResponse。
流RequestStream
请求方发送一个请求报文,响应方发回N个响应报文。传统的MQ是典型的RequestStream。
通道RequestChannel
创建一个通道上下文,双方可以互相发送消息。IM是个典型的RequestChannel通讯场景。
2 双向通讯Bi-Directional
RSocket的Client连接到Server,这个过程称为Setup,在连接成功后,会约定收发消息的方向逻辑:
- 当Client请求Server时,发送的请求ID永远为奇数
- 当Server请求Client时,发送的请求ID永远为偶数
正是因为这个奇偶性确定方向的特性,不同于传统的如HTTP请求,RSocket可以做到双向请求。
3 其他
- 二进制协议,紧凑高效
- 多路复用
- 基于帧(Frame)的背压,与ReactiveStreams语义契合
- 灵活的传输层切换: TCP/UDP/WebSocket等
- 支持Cancel、断点续传、租约等高级特性
综上与HTTP做一些比较,RSocket的效率更高,支持的通讯场景更丰富,也没有队头阻塞的问题。与SocketIO这种基于纯事件的框架相比,RSocket的请求具有很清晰的上下文,API精炼易用。
二 RSocket的内部实现
1 帧的设计
帧(Frame)是RSocket协议报文的最小单位。
- 一个帧由6 bytes的Header和剩余的Body构成,其中Header的4 bytes表示 StreamID,6 bits表示Frame Type, 10 bits作为Flags。Body根据不同的帧类型,结构也不同,常用的带Payload的帧一般会包括Metadata和Data两个部分。
- 传输层如果本身不支持分帧特性的(如TCP),那么RSocket会用3 bytes的uint24表示帧长度,所以最大的帧大小是16MB。
- 如果帧超出16MB,RSocket支持帧分裂重组,也就是拆成更小的帧,接收端再自动重组。
2 数据载体——Payload
基于帧之上,一般开发者接触到的是Payload, 它类似一个HTTP报文,可以是一个Request,也可以是一个Response。由两个二进制部分组成:
- Metadata——元数据,类似HTTP的header
- Data——数据,类似HTTP的body
3 架构
这里基于笔者在实现Golang版SDK的基础上整理的架构图,Java版基本也类似。
- Transport层将网络二进制流编解码为Frames。
- RSocket支持自定义最大Frame Size,默认16MB,当某个Frame超出时,会被拆解为N个小Frame,收到时再重组,在介绍帧的时候也提到了,这个特性称为Fragmentation。
- DuplexConnection转换Frames为Payload,抽象为一个个Request/Response上下文,并负责读写。
- RSocket组装Connection为RSocket Interface,其中Resumable支持断点续传,连接断开重连也能自愈,个人觉得这个特性有点鸡肋,在弱网环境有些优势,但是因为期间会缓存住未处理完毕的帧,所以会耗费大量的系统资源。
- RSocket使用Reactor核心库暴露为4种通讯模式,抽象为高级API。
4 玩法
RSocket有很多玩法,传统的RPC自然不在话下,用来做IM也未尝不可,某些特性也可以用来做代理或者网络穿透。
IoT的场景,比如小明的家里有个智能空调,小明想在外面通过手机APP来控制空调开关,如何优雅地描述这个控制问题?最精炼的解决方案就是"小明调用空调上开关的API"。
另外最经典的玩法就是Broker了,Broker类似一种“软路由”的方案,可以让服务的发布访问变得简单。发布服务只要连接到Broker,调用方通过反向请求的方式来让Broker透明转发即可,摒弃了传统的注册中心,端口管理等常见的服务治理手段。
5 关于RSocket Broker
Broker有很多优势,发布服务不需要监听端口,无需Sidecar,服务注册变得简单,无需zk、etcd之类,LoadBalance变得简单,也更安全,没监听端口后很难攻击。也有很多劣势,网络上多了一跳,性能是有一定损耗的,Broker是中心化设计,类似我们平时全局的Nginx一样,但是Broker的优雅启停显然更加复杂,受限于整个Broker集群的瓶颈等等。上帝为你关闭了一扇门,就一定会为你打开一扇窗。
目前高德落地的FaaS中大量使用了基于RSocket架构的集团Broker,支撑了今年的五一长假,峰值QPS超20万,平稳零故障。
这里笔者也准备了一个教学用的Mini Broker,演示了两个浏览器之间相互上下文调用彼此服务的场景,有兴趣的同学可以查看。
三 响应式编程
响应式编程是个老话题了,它早已无处不在,甚至你在Excel里SUM求和,本质上也是种响应式的思维。响应式本质上就是响应变化的数据流。RSocket这个协议本身就是以响应式之名,将其扩展到网络层面。
1 响应式编程大概长这样
而在我们平时工作中,必然会引入各种操作和变换:
2 Reactive Streams
JDK推出了响应式标准API,撇开Processor之外,其核心接口就Publisher/Subscriber/Subscription,非常精炼。
- Publisher:发布者,负责生产数据。唯一的方法subscribe,接收一个Subscriber开始一次新的订阅。
- Subscriber:订阅者,负责订阅消费数据。
- Subscription:订阅,某次订阅的上下文控制,如取消、通知获取下N条数据。
Spring的Reactor是一个标准的实现,其一次完整的执行过程如下图:
- 创建subscriber,开始订阅Publisher。
- 生成上下文subscription。
- Publisher就绪,调用onSubscribe。
- Publisher开始生产数据。
- 每条成功生产的数据回调onNext。
- 当生产失败时,回调onError并结束当前订阅。
- 当所有数据生产完毕时,回调onComplete并结束当前订阅。
- 中途可以调用subscription随时cancel取消订阅,或者通过request(n)通知生产下N个元素,这个过程即背压。
由于Java天生的语言优势,很适合使用RxJava或Reactor之类的框架,代码逻辑清晰可读性会非常高。笔者在实现Go版的Reactor时,深深地体会到了没有泛型支持的API表现力是多么匮乏,也期待Go2的泛型能够有所改善。
四 总结
RSocket是个很有趣的网络协议,它可能不会普及流行,但贵在它解决问题的思路和设计很令人耳目一新。如果大家有兴趣,可以去它的官网了解下。
原文链接
本文为阿里云原创内容,未经允许不得转载。
浅谈RSocket与响应式编程相关推荐
- 浅谈滴滴需求响应式公交背后的技术
桔妹导读:所谓需求响应式公交,就是根据用户出行需求,提供非固定路线的.能够实时拼单的公交系统.目前滴滴动态公交可通过灵活调配运力.实时规划行驶路线,为用户提供经济.直达.有座.高效的响应式公交服务. ...
- 响应式编程之网络新约:RSocket
响应式reactive是Java中高效应用的下一个前沿,但它目前主要有两个障碍:数据访问和网络.RSocket是一种新的第7层语言无关的应用网络协议(解决后者),它由Facebook,Netifi和P ...
- 浅谈Spring5 响应式编程
目录 为什么是响应式编程 用于响应式编程实现的理想案例 响应流 (Reactive Streams) Spring 5 提供的响应式编程 Spring Web Reactive vs. Spring ...
- 编程范式:函数式编程防御式编程响应式编程契约式编程流式编程
不长的编码生涯,看到无数概念和词汇:面向对象编程.过程式编程.指令式编程.函数式编程.防御式编程.流式编程.响应式编程.契约式编程.进攻式编程.声明式编程--有种生无可恋的感觉. 本文试图加以汇总和整 ...
- Spring笔记(4):响应式编程、Reactor、WebFlux、Flow
目录 1.Spring Webflux 介绍 2.响应式编程(Java 实现) 3.响应式编程(Reactor 实现) 4.SpringWebflux 执行流程和核心 API 5.SpringWebf ...
- 赠书:响应式编程到底是什么?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 最近几年,随着Go.Node 等新语言.新技术的出现,J ...
- 阿里淘宝一直在推的响应式编程到底是个什么鬼?
随着这些年智能手机的发展和普及,我们的服务器端要应对日益增长的巨大流量. 从开发的角度来看,这就要求我们必须设计出高扩展性和高可用性的程序,以确保能够适应日益增长的请求所带来的压力. 而从使用者的角度 ...
- Reactive(1) 从响应式编程到好莱坞
目录 概念 面向流设计 异步化 响应式宣言 参考文档 概念 Reactive Programming(响应式编程)已经不是一个新东西了. 关于 Reactive 其实是一个泛化的概念,由于很抽象,一些 ...
- 【技术干货】跨境茶话会第4期丨响应式编程的应用
大师兄说 许多场景下为了更迅速的响应客户端的请求,将问题转化为实时反映业务状态的变化,能更好地提升用户体验以及支撑更大量的用户请求,于是催生了响应式编程,本期跨境茶话会仍旧邀请了中美两地的相关专家来谈 ...
最新文章
- Django入门之开发环境搭建1.1
- SpringMVC @RequestBody接收Json对象字符串
- Android Activity和Fragment的转场动画
- 论文浅尝 - ICLR2021 | BERTology 遇上生物学:在蛋白质语言模型中解释注意力
- 【STM32】【STM32CubeMX】STM32CubeMX的使用之一:工程建立之点亮你的LED
- 转载 linux系统调用和库函数调用的区别
- Bootstrap学习(一):Bootstrap简介
- Bootstrap模态出现在背景下
- OpenCV图像处理(3)——盒维数计算
- JavaScript学习笔记 及 JAVAScript优化
- 读react.js小书 中组件的render的方法(从零学react)
- 开源项目之Windows读取Ext4分区的工具 Ext2Read
- 质点系的角动量与角动量定理
- mongodb数据的导入导出备份恢复
- Java面向对象 - String类
- html制作网页文字颜色代码,html网页设计教程关于html字体颜色设置方法是什么?...
- Linux用户和组权限管理
- WebBrowser控件的多页面浏览(Tabbed Browsing)开发接口
- 【VR】详解 Facebook Oculus团队的手势追踪系统——MegaTrack
- ubuntu linux原生微信使用体验
热门文章
- JAVA入门级教学之(static关键字)
- vue实现上下滑动翻页_vue 实现滚动到底部翻页效果(pc端)
- 审计工作存在的难点和问题_电力工程造价审计的难点与对策有哪些?学习安装电力造价广联达计价看这里!!...
- Java环境的正确配置你会了吗?
- 【LeetCode笔记】312. 戳气球(Java、动态规划)
- linux环境特性的文件夹,在Linux环境下如何消减可执行文件或者动态库的大小
- 从数据类型 nvarchar 转换为 numeric 时出错_JS入门篇(三):javascript的数据类型详解...
- 调用kmeans_聚类分析—KMeans
- 正交变换在基下的矩阵都是可逆阵_矩阵分析与应用(一,矩阵基础知识)
- 定值保险计算举例_保险公司的“开门红”又要来了!理财险真的值得买吗?