Netty(一) 之 I/O通信
IO类型介绍
BIO通信
- 一个线程负责连接
- 一请求一应答
- 缺乏弹性伸缩能力
由于线程是宝贵的资源,会造成宕机。
请求来到,由accpter去针对每个请求申请线程
伪异步IO通信
- 线程池负责连接
- M请求N应答
- 超过线程池会阻塞,由于限制不会宕机
由线程池来处理所有客户端的接入,
NIO通信
- 加入了缓冲区Buffer:所有数据由缓冲区处理,读入缓冲区,写入缓冲区。
- 通道Channel:是双向的,读写可以同时进行
- 多路复用器Selector:会不断轮询注册在Selector上的Channel,当发现Channel发生了读写事件,选中它,根据SelectionKey,获取就绪Channel集合,进行IO操作。 由于JDK使用了epoll,代替传统的seletc实现,没有最大连接数限制,可以介入无线客户端。
AIO通信 异步通信Io
- 连接注册读写事件和回调函数
- 读写方法异步
- 主动通知程序。一、通过future类表示异步操作结果 二是传入Channel.completion.handle接口的实现类,作为操作完成回调。
- 它不需要多路复用器Selector进行轮询,是被动回调的
四种IO对比
客户端个数:
| 类型 | BIO | 伪异步IO | NIO| AIO
| ——– | :—–: | :—-: |:—-:|:—-:
| 客户端:线程个数 | 1:1 | m:n |m:1|m:0
| IO类型 | 阻塞同步 | 阻塞同步 | 非阻塞同步|非阻塞异步
| 使用难度 | 简单 | 简单 | 最复杂|复杂
| 调试难度 | 简单 | 简单 | 复杂|复杂
| 可靠性 | 低 | 低 | 可靠|可靠
| 吞吐量 | 低 | 较低 | 较高|高
Netty入门
原生NIO缺陷
- 类库和API繁杂:
- 入门门槛高:熟悉多线程,网络编程
- 工作量和难度大:面临断连重连,网络闪断,断包读写,失败缓存
- JDK NIO些许BUG 如著名的epoll BUG,会导致空轮询,导致cpu占用满
Netty优势
duboo使用Netty作为底层通信框架,其他RPC框架也使用Netty构建高性能异步通信能力
- API简单,扩展灵活
- 入门门槛低,支持多种主流协议
- 性能高,成熟稳定,处理了所有JDKbug,经受了大量商用考验
WebSocket 基于TCP
- 是一个H5协议规范
- 握手机制, 建立TCP连接,进行实时通信
- 解决客户端于服务端实现通信 的技术
优点:
- 节省通信开销:原本的WebService是,间隔若干秒,发送请求将服务器消息拉回来,需要不断发送请求,header是很长的,内容很小,会很占用资源
- 服务器主动 传送数据 给客户端
- 实时通信,不需要发送请求,不仅限于Ajax方式通信,可以彼此相互推送,实现实时通信。
建立连接
- 客户端发起握手请求 附加头 UpgradeWebSocket
- 服务器端相应请求 解析附加头 生成应答消息相应
- 连接建立
生命周期
- 打开事件:发生在连接时,WebSocket Session对象(表示已经建立好的连接) 、配置对象(包含配置端点信息)、一组路径参数(握手时,入栈匹配的url)
- 消息事件:三种基本消息(文本消息,二进制消息,pown消息),对应的使用String,byte,pomMessage实例
- 错误事件:连接发生错误时,处理入栈任何异常(连接建立错误SessionException、WebSocket将消息解码成开发人员所需要时,DecodeException)