Netty知识点
以前仅仅只是听说过Netty,还没有系统的学习过,借助这个机会领略下Netty的风采
Netty的兴起主要是随着网络的普及,Java的网络编程愈发的重要,面对高并发的场景,Java1.4提供的NIO是非常难用的,Netty相当于是对NIO进行了一次封装,简化了用法
目前使用到了Netty的项目非常多,如ElasticSearch、Spring Cloud Gateway、Dubbo
BIO、NIO和AIO的区别
BIO:传统的阻塞IO,在1.0的时候就已经存在了,是比较传统的IO方式,单个线程在进行IO操作的时候会直接阻塞,属于同步阻塞IO,在QPS不是很大的时候,每个线程各司其职,井井有条,是非常好的IO模型,但是随着请求数量的增加,线程重量级的特性体现了出来,无法应付,于是1.4提出了NIO
NIO:同步非阻塞IO,线程通过和Selector打交道,从而可以同时操作多个Channel,每个Channel分别管理着一份buffer,NIO是面向Buffer的,可以实现更高的并发量,但是在并发量较小的时候还是推荐直接使用BIO,易维护,可以通过池化资源来减小线程开销
AIO:1.7提出的异步非阻塞IO模型,是基于事件和回掉机制来完成的,NIO在调用线程发出指令后,可以进行其他线程,但是到最后还是需要进行同步操作,等待IO的执行完成,但是AIO是不需要的,可以直接返回,AIO提供的回掉机制可以帮忙完成同步操作,但是使用起来非常困难。Netty之前尝试过使用,但是放弃了。
Netty是基于NIO之上的基于Client-Server的网络编程模型,优化了TCP,UDP套接字,并且还支持多种应用层协议如HTTP,FTP等
Netty和NIO的一个比较(Netty的优势)
成熟稳定,很多大型项目如ElasticSearch、Dubbo都使用到了Netty
在保证安全性和性能的前提下做到了易开发和维护
统一的API,直接支持阻塞和非阻塞的操作
安全性有保障,自带SSL/TLS支持
具体使用场景:Netty真是一个造轮子的好帮手,可以说是一个造框架的框架了,如实现RPC远程调用,自定义HTTP服务器,通信系统,消息推送系统
Netty的核心组件:
ByteBuf:字节容器,Netty操作数据的基本单位,相当于是NIO当中的ByteBuffer
BootStrap和ServerBootStrap:客户端和服务端的启动引导类
Channel:作为数据传输的一个通道,类似于Java BIO当中的Stream的概念
EventLoop:事件循环,说白了NIO是基于事件驱动的,那么Netty也是,绝对的核心,负责监听网络事件并调用相关操作
下面就是一些编程模型的知识点了
Reactor编程模型(反映式编程模型):局域事件驱动,特别适合处理海量请求
Reactor可以细分为单线程Reactor,多线程Reactor以及主从多线程模型
单线程主要是所有请求都交给一个线程去调用Selector,来完成对应事件匹配到事件处理器上,优点是消耗特别少,缺点也非常明显,因为只有一个线程,可能无法处理表现出高延迟
多线程Reactor就是解决单线程Reactor在并发量大的时候的高延迟问题,引入了线程池,每个线程都持有一个Selector完成事件的匹配,由一个父线程来完成对事件的监听,但是监听到事件后不是直接进行匹配,而是交给线程池中的子线程去完成匹配工作,这样就提高了吞吐量,降低了延迟(主要耗费的时间还是在匹配Handler上),但是如果是上百万的请求,这个模型还是顶不住,因为始终只有一个线程进行事件的监听,哪怕调用子线程池去处理费时操作,延迟依旧会上来
此时需要使用主从多线程Reactor,一组线程池中的线程负责监听事件并将事件发送给另一组线程池,另一组线程池中的线程进行事件与事件处理器Handler的匹配
Netty的线程模型
Netty也是基于Reactor线程模型开发的,支持以上三种模型,使用分别为:
因此,具体的执行逻辑即为:创建两个EventLoopGroup,分别作为客户端的boss和worker,通过NioEventLoopGroup的构造方法指定线程个数,如果没有指定则是CPU线程数(通过Runtime中的信息获取到的)*2 。
然后创建服务器的引导类ServerBootstrap,通过ServerBootstrap的group方法实现对boss和child的装载,此时有三种状态:单线程,多线程,主从多线程。然后书写对应的业务处理逻辑即可。
最后更新于