Netty如何实现高性能?
性能是设计出来的,不是测试出来的。Netty采用以下设计实现高性能:数据库
- 采用异步非阻塞的I/O类库,基于Reactor模式实现,解决了传统同步阻塞I/O模式下一个服务端没法平滑处理线性增加的客户端的问题
- TCP接收和发送缓冲区使用直接内存代替堆内存,避免了内存复制,提高了I/O读取和写入的性能
- 支持经过内存池的方式循环利用ByteBuf,避免了频繁建立和销毁ByteBuf带来的性能损耗。
- 可配置的I/O线程数、TCP参数等,为不一样的用户场景提供定制化的调优参数,知足不一样的性能场景
- 采用环形数组缓冲区实现无锁化并发编程,代替传统的线程安全容器或者锁
- 合理使用线程安全容器、原子类等,提高系统的并发处理能力
- 关键资源的处理使用单线程串行化的方式,避免多线程并发访问带来的锁竞争和额外的CPU资源消耗问题
- 经过引用计数器及时的申请释放再也不被引用的对象,细粒度的内存管理下降了GC的频率,减小了频繁GC带来的时延增大和CPU损耗
可靠性
做为一个高性能的异步通讯框架,架构的可靠性是你们选择的一个重要依据。下面咱们探讨Netty架构的可靠性设计:编程
- 因为长链接不须要每次发送消息都建立链路,也不须要在消息交互完成时关闭链路,所以相对于短链接性能更高。对于长链接,一旦链路创建成功便一直维系双方之间的链路,知道系统推出。 为保证长链接的链路有效性,每每须要经过心跳机制周期性的进行链路检测。使用周期性心跳的缘由是:在系统空闲时,例如凌晨,每每没有业务消息。若是此时链路被防火墙hang住,或者遭遇网络闪断、网络单通等,通讯双方没法识别出这类链路异常。等到次日业务高峰期到来时,瞬间的海量业务冲击会致使消息积压没法发送给对方,因为链路的重建须要时间,这期间业务大量失败(集群或者分布式组网状况会好一些)。为了解决这个问题,须要周期性的心跳对链路进行有效性检测,一旦发生问题,能够及时关闭链路,重建TCP链接。 当有业务消息时,无需心跳检测,能够由业务消息进行链路可用性检测。因此心跳消息每每是在链路空闲时发送的。 为了支持心跳,Netty提供了以下两种链路空闲检测机制。
- 读空闲超时机制:当连续周期T没有消息可读时,触发超时Handler,用户能够基于读空闲超时发送心跳消息,进行链路检测;若是连续N个周期任然没有读取到心跳信息,能够主动关闭链接。
- 写空闲超时机制:当连续周期T没有消息要发送时,出发超时Handler,用户能够基于写空闲超时发送心跳消息,进行链路检测;若是联系N个周期仍然没有接收到对方的心跳消息,能够主动关闭链路。 为了知足不一样用户场景的心跳定制,Netty提供了空闲状态检测事件通知机制,用户能够订阅空闲超时事件、写空闲超时事件、读或者写超时事件,在接收到对应的空闲事件以后,灵活的进行定制。
- 内存保护机制 Netty提供多种机制对内存进行保护,包括如下几个方面:
- 经过对象引用计数器对Netty的ByteBuf等内置对象进行细粒度的内存申请和释放,对非法的对象引用进行检测和保护。
- 经过内存池来重用ByteBuf,节省内存
- 可设置的内存容量上限,包括ByteBuf、线程池线程数等
- 优雅停机 相比于Netty的早期版本,Netty5.0版本的优雅退出功能作的更加完善。优雅停机功能指的是当系统退出时,JVM经过注册的ShutDown Hook拦截到退出信号量,而后执行退出操做,释放相关模块的资源占用,将缓冲区的消息处理完成或者清空,将待刷新的数据持久化到磁盘或者数据库中,等到资源回收和缓冲区消息处理完成后,再退出。
可定制性
Netty的可定制性主要体如今如下几点:数组
- 责任链模式:ChannelPipeline基于责任链模式开发,便于业务逻辑的拦截、定制和扩展。
- 基于接口的开发:关键的类库都提供了接口或者抽象类,若是Netty自身的实现没法知足用户的需求,能够由用户自定义实现相关接口
- 提供了大量工厂类,经过重载这些工厂类能够按需建立出用户实现的对象
- 提供了大量的系统参数供用户按需设置,加强系统的场景定制性
可扩展性
基于Netty的基础NIO框架,能够方便地进行应用层协议定制,例如HTTP协议栈、Thrift协议栈、FTP协议栈等。这些扩展不须要修改Netty的源码,直接基于Netty的二进制类库便可实现协议的扩展和定制。 目前,业界存在大量的基于Netty框架开发的协议,例如基于Netty的HTTP协议、Dubbo协议、RocketMQ内部私有协议等。安全
参考文献:《Netty权威指南》网络