【总结】Netty(RPC高性能之道)原理剖析

1,Netty简述
  • Netty 是一个基于 JAVA NIO 类库的异步通信框架,用于创建异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性的网络客户端服务器端
  • RPC高性能分析,请参考文章“【总结】RPC性能之道 ”
  • 特点
    • 异步、非阻塞、基于事件驱动的NIO框架
    • 支持多种传输层通信协议,包括TCP、UDP等
    • 开发异步HTTP服务端和客户端应用程序
    • 提供对多种应用层协议的支持,包括TCP私有协议、HTTP协议、WebSocket协议、文件传输
    • 默认提供多种编解码能力,包括Java序列化、Google的ProtoBuf、二进制编解码、Jboss marshalling、文本字符串、base64、简单XML等,这些编解码框架可以被用户直接使用
    • 提供形式多样的编解码基础类库,可以非常方便的实现私有协议栈编解码框架的二次定制和开发
    • 经典的ChannelFuture-listener机制,所有的异步IO操作都可以设置listener进行监听和获取操作结果
    • 基于ChannelPipeline-ChannelHandler的责任链模式,可以方便的自定义业务拦截器用于业务逻辑定制
    • 安全性:支持SSL、HTTPS
    • 可靠性:流量整形、读写超时控制机制、缓冲区最大容量限制、资源的优雅释放
    • 简洁的API和启动辅助类,简化开发难度,减少代码量
  • 为什么不是传统的IO
    • 线程模型存在致命缺陷一连接一线程的模型导致服务端无法承受大量客户端的并发连接
    • 性能差频繁的线程上下文切换导致 CPU 利用效率不高
    • 可靠性差:由于所有的 IO 操作都是同步的,所以业务线程只要进行 IO 操作,也会存在被同步阻塞的风险,这会导致系统的可靠性差依赖外部组件的处理能力网络的情况
  • 使用NIO,同步阻塞 IO 的三个缺陷都将迎刃而解
    • NIO 采用 Reactor 模式,一个 Reactor 线程聚合一个多路复用器 Selector,它可以同时注册、监听和轮询成百上千个 Channel,一个 IO 线程可以同时并发处理N个客户端连接,线程模型优化为1:N(N < 进程可用的最大句柄数)或者 M : N (M通常为 CPU 核数 + 1, N < 进程可用的最大句柄数)
    • 由于 IO 线程总数有限,不会存在频繁的 IO 线程之间上下文切换和竞争,CPU 利用率高
    • 所有的 IO 操作都是异步的,即使业务线程直接进行 IO 操作,也不会被同步阻塞,系统不再依赖外部的网络环境和外部应用程序的处理性能
    • 切换到 NIO 编程之后可以为系统带来巨大的可靠性、性能提升,所以,目前采用 NIO 进行通信已经逐渐成为主流
  • 为什么不直接使用JDK NIO类库
    • NIO的类库和API繁杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等
    • 需要具备其它的额外技能做铺垫,例如熟悉Java多线程编程,因为NIO编程涉及到Reactor模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的NIO程序
    • 可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等等,NIO编程的特点是功能开发相对容易,但是可靠性能力补齐工作量和难度都非常大
    • JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,最终导致CPU 100%。官方声称在JDK1.6版本的update18修复了该问题,但是直到JDK1.7版本该问题仍旧存在,只不过该bug发生概率降低了一些而已,它并没有被根本解决
    • 一个高性能、高可靠性的 NIO 服务端开发和维护成本都是非常的,开发者需要具有丰富的 NIO 编程经验和网络维护经验,很多时候甚至需要通过抓包来定位问题
    • 开发出一套 NIO 程序需要 1 个月,但是它的稳定很可能需要 1 年甚至更长的时间
    • Netty 的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指
2,Netty原理
  • Netty逻辑架构
    • 第一层
      • Reactor 通信调度层,它由一系列辅助类组成,包括 Reactor 线程NioEventLoop 以及其父类、NioSocketChannel/NioServerSocketChannel 以及其父类、ByteBuffer 以及由其衍生出来的各种 Buffer、Unsafe 以及其衍生出的各种内部子类等
    • 第二层
      • 职责链 ChannelPipeLine,它负责调度事件职责链中的传播,支持动态编排职责链,职责链可以选择性的拦截自己关心的事件,对于其它IO操作和事件忽略,Handler同时支持inboundoutbound事件
    • 第三层
      • 业务逻辑编排层,业务逻辑编排层通常有两类:一类是纯粹业务逻辑编排,还有一类是应用层协议插件,用于协议相关的编解码链路管理,例如 CMPP 协议插件
  • 灵拷贝
    • “零拷贝”是指计算机操作的过程中,CPU不需要为数据在内存之间的拷贝消耗资源。而它通常是指计算机在网络上发送文件时,不需要文件内容拷贝到用户空间(User Space)直接在内核空间(Kernel Space)中传输到网络的方式
    • Netty的“零拷贝”主要体现在三个方面
      • Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内存Buffer拷贝一份到直接内存中,然后才写入Socket中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝
  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值