Netty框架简介
概览
- https://netty.io/
- 网络应用开发框架
- 异步
- 事件驱动
- 基于NIO
- 适用于
- 服务端
- 客户端
- TCP/UDP
- 特性
- 高吞吐
- 低延迟
- 低开销
- 零拷贝
- 可扩容
- 松耦合
- 使用方便可维护
Server分级
- HTTP Server
- 只实现基础的HTTP协议
- 无状态
- Web Server
- 在HTTP Server之上支持Web组件
- Session机制、JSP等
JavaEE
Channel
- 通道
- NIO中的基础概念,代表一个打开的连接,可执行读取/写入IO操作
- netty对Channel的所有IO操作都是非阻塞的
- ChannelFuture
- Java的Future接口,只能查询操作的完成情况或阻塞当前线程等待操作完成
- netty封装一个ChannelFuture接口,我们可以将回调方法传给ChannelFuture,操作完成时自动执行
- ChannelPipline
- 数据处理管道就是事件处理器链
- 有顺序、同一个Channel的出站处理器和入站处理器在同一个列表中
- Event&Handler
- 基于事件驱动
- 事件和处理器可以关联到入站和出站数据流
- 入站事件
- 通道激活和停用
- 读操作事件
- 异常事件
- 用户事件
- 出站事件
- 打开连接
- 关闭连接
- 写入数据
- 刷新数据
- 事件处理程序接口
- ChannelHandler
- ChannelOutboundHandler
- ChannelInboundHandler
- 适配器(空实现,需要继承使用)
- ChannelInboundHandlerAdapter
- ChannelOutboundHandlerAdapter
Encoder&Decoder
网络事件
- 应用程序逻辑事件
-
使用示例
Netty原理
启动和处理流程
高性能
指标
高并发用户ConcurrentUsers(业务角度)
- 日活/月活
- 同时在线
- 高吞吐量Throughout(技术角度)
- QPS
- TPS
- 低延迟Latency(技术角度)
- RT 响应时间是从用户角度看
- Latency 延迟时间是从系统内部看,不包括RT中的网络延迟时间
- 通常要重点观测P90/P99的延迟分布
```shell
wrk -c 40 -d 30s —latency http://localhost:8088
-c 40 指并发连接40
得到的QPS/TPS 指吞吐量
得到的latency 指延迟,
<a name="Lfq0w"></a>### 副作用- 系统复杂度- 建设与维护成本- 故障或Bug导致的破坏性<a name="cm3Sp"></a>### 应对策略- 稳定性建设(混沌工程、Netflix公司的SpringCloud类似解决方案)- 容量(系统现状和业务需求)- 爆炸半径(微服务拆分)- 工程方面积累与改进(变更流程控制和技术研究)<a name="ljNYy"></a>## 如何实现高性能<a name="EjqF0"></a>### 统一开发框架- 异步- 事件驱动- 基于NIO<a name="Fcnwn"></a>### 事件处理机制<a name="z6fSo"></a>### 从事件驱动机制到Reactor模型- Reactor模型首先是事件驱动的- 有一个或多个并发输入源- 有一个ServiceHandler和多个EventHandlers- ServiceHandler会同步的将输入的请求多路复用的分发给相应的EventHandler<a name="cYXws"></a>### 从Reactor模型到NettyNIO- BossEventLoopGroup- WorkerEventLoopGroup<br /><a name="iter8"></a>## 关键对象<a name="yH5Po"></a>### 全局- Bootstrap:启动线程,开启socket- EventLoopGroup/EventLoop- SocketChannel:连接- ChannelInitializer:初始化- ChannelPipline:处理器链- ChannelHandler:处理器<br /><a name="ylEcV"></a>### ChannelPipline<a name="KOm3k"></a>### Event&Handler- 入站事件- 通道激活和停用- 读操作事件- 异常事件- 用户事件- 出站事件- 打开连接- 写入数据- 刷新数据- 关闭连接- 事件处理程序接口- ChannelHandler- ChannelInboundHandler- ChannelOutboundHandler- 适配器(空实现,需要继承使用)- ChannelInboundHandlerAdapter- ChannelOutboundHandlerAdapter<a name="VmTgb"></a>## 三种模式<a name="2w9xB"></a>### Reactor单线程模型```javaEventLoopGroup elg = new NioEventLoopGroup(1);ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(elg);
非主从Reactor多线程模型
EventLoopGroup elg = new NioEventLoopGroup(); // 默认2倍的cpu核心数ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(elg);
主从Reactor多线程模型
EventLoopGroup bossGroup = new NioEventLoopGroup(); // 默认2倍的cpu核心数
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 默认2倍的cpu核心数
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup);
Netty网络程序优化
粘包与拆包
- 都是人为的上层问题,没有协商好ContentLength,和底层的TCP没有关系
- 解决方案就是协商好包的边界/ContentLength
- TCP有粘包问题,HTTP/UDP没有,因为UDP是单工的,HTTP做了校验
- ByteToMessageDecoder提供的一些常见的实现类:
- FixedLengthFrameDecoder
- 定长解码器
- 可以指定固定的字节数算一个完整的报文
- LineBasedFrameDecoder
- 行分隔符解码器
- 遇到\n或\r\n则认为是一个完整的报文
- DelimiterBasedFrameDecoder
- 分隔符解码器
- 分隔符可以自己指定
- LengthFieldBasedFrameDecoder
- 长度编码解码器
- 将报文划分为报文头/报文体
- JsonObjectDecoder
- json格式解码器
- 检测到匹配数量的{} 或 []时,则认为是一个完整的Json对象或Json数组
- FixedLengthFrameDecoder
Nagle与TCP_NODELAY
- 概念
- MTU:MaximumTransmissionUnit 最大传输单元,标准1500
- MSS:MaximumSegmentSize 最大分段大小,标准1460(=1500-20字节的IP头-20字节的TCP头)
- MSL:MaximumSegmentLifetime 最大分段生命值,标准1/2分钟
- 网络拥堵与Nagle算法优化,为了最高效实现通信,需要对网络进行优化,避免应用层直接发送/接收数据
- 操作系统真正发送网络包的条件
- 缓冲区满
- 达到超时(200ms)
TCP_NODELAY
TCP经过2MSL后被真正释放优化点
- 降低MSL时间
- 重用TIME-WAIT阶段被占用的端口
Netty优化
- 不要阻塞EventLoop
- 系统参数优化
- ulimit -a 调整fd
- /proc/sys/net/ipv4/tcp_fin_timeout或windows的注册表中的TcpTimedWaitDelay
- 缓冲区优化
- SO_RCVBUF 通常设置为32K
- SO_SNDBUF 通常设置为32K
- SO_BACKLOG 未正常建立连接的连接记录
- REUSEXXX
- 心跳周期优化
- 心跳机制
- 心跳周期,如果一直有数据传输则关闭心跳
- 心跳频率
- 断线重连
- 心跳机制
- 内存与ByteBuffer优化
- DirectBuffer
- HeapBuffer
其他优化
请求接入
- 作为所有API接口服务请求的接入点
- 业务聚合
- 作为所有后端业务服务的聚合点
- 中介策略
- 实现安全、验证、路由、过滤、流控等策略
统一管理
流量网关(关注稳定与安全)
- 全局性流控
- 日志统计
- 防止SQL注入
- 防止Web攻击
- 屏蔽工具扫描
- 黑白IP名单
- 证书/加解密处理
业务网关(提供更好的服务)
流量网关(高性能)
- OpenResty
- Kong
业务网关(扩展性好,适合二次开发)
Netflix开源的API网关系统
- 主要设计目标是动态路由、监控、弹性、安全
- 内部可以看作不同功能filter的集合,最主要的就是pre、routing、post三种过滤器
zuul2
- 基于netty内核重构
SpringCloudGateway
实践
- 参考下面代码的nio02
https://github.com/JavaCourse00/JavaCourseCodes
- 架构设计
- 设计:技术复杂度和业务复杂度
- 抽象:理清概念,正确命名
- 组合:组件之间的相互关系
