概述
Netty是一个致力于创建高性能网络应用程序的成熟的IO框架,相比较与直接使用底层的Java IO API, 你不需要先成为网络专家就可以基于Netty去构建复杂的网络应用。有很多开源中间件,它们的底层都使用了Netty
学习Netty之前我们需要认识主要的I/O模型
四类主要的I/O模型
- 同步阻塞IO(Blocking IO)
- 同步非阻塞IO(Non-blocking IO)
这里所说的NIO(同步非阻塞IO)模型,并非Java的NIO(New IO)库 - IO多路复用(IO Multiplexing)
即经典的Reactor反应器设计模式,有时也称为异步阻塞IO, Java中的Selector选择器和Linux中的epoll都是这种模型。 - 异步IO(Asynchronous IO)
异步IO,指的是用户空间与内核空间的调用方式反过来。用户空间的线程变成被动接受者,而内核空间成了主动调用者。这有点类似于Java中比较典型的回调模式,用户空间的线程向内核空间注册了各种IO事件的回调函数,由内核去主动调用。
※Linux中因为不完善,所以性能和IO多路复用差别不是很大,所以Netty是基于IO多路复用模型,而不是AIO
java中的NIO库
问 啥是NIO?
NIO 全称是Non-Blocking IO,也就是同步非阻塞IO(因为是对jdk1.4中原有的I/O功能做了改进,所以也称之为新I/O 即New-I/O)
NIO的特性
- 面向缓冲区(Buffer)
- 选择器(Selectors)
选择器用于监听多个管道的事件,使用传统的阻塞时可以方便的知道什么时候可以进行读写,而使用非阻塞通道,选择器可以让我们知道什么时候通道准备好了 - 非阻塞模式
- 管道(Channel)
管道(Channel):管道实际上就像传统IO中的流,到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象
目前常见的NIO框架
- Netty(主流版本为4.1)
- Mina
- Grizzly
Netty
Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。
netty 使用场景
- 互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少
- 游戏行业:Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈。
非常方便定制和开发私有协议栈,账号登录服务器,地图服务器之间可以方便的通过 Netty 进行高性能的通信 - 大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨界点通信,它的 Netty Service 基于 Netty 框架二次封装实现。还有著名的Kafka 底层也采用了Netty
对比传统BIO、IO复用模型、Netty 的非阻塞I/O模型
说明:
每个请求都需要独立的线程完成数据 Read,业务处理,数据 Write 的完整操作问题。当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费
说明:
在 I/O 复用模型中,会用到 Select,这个函数也会使进程阻塞,但是和阻塞 I/O 所不同的是这两个函数可以同时阻塞多个 I/O 操作。
而且可以同时对多个读操作,多个写操作的 I/O 函数进行检测,直到有数据可读或可写时,才真正调用 I/O 操作函数。
Netty 的非阻塞 I/O 的实现关键是基于 I/O 复用模型,这里用 Selector 对象表示:
说明:
Netty 的 IO 线程 NioEventLoop 由于聚合了多路复用器 Selector,可以同时并发处理成百上千个客户端连接。
当线程从某客户端 Socket 通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。线程通常将非阻塞 IO 的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。
由于读写操作都是非阻塞的,这就可以充分提升 IO 线程的运行效率,避免由于频繁 I/O 阻塞导致的线程挂起。
一个 I/O 线程可以并发处理 N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞 I/O 一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。
Linux文件句柄数限制
在Linux下,通过调用ulimit命令,可以看到单个进程能够打开的最大文件句柄数量。
对于高并发、高负载的应用,就必须要调整这个系统参数,以适应处理并发处理大量连接的应用场景
#查看
> ulimit -n
#修改
> ulimit -n 500000
终极解除Linux系统的最大文件打开数量的限制,可以通过编辑Linux的极限配置文件/etc/security/limits.conf来解决,修改此文件,加入如下内容
#软性极限
soft nofile 500000
#硬性极限
hard nofile 500000
※在使用和安装目前非常火的分布式搜索引擎——ElasticSearch,就必须去修改这个文件,增加最大的文件句柄数的极限值
在服务器运行Netty时,也需要去解除文件句柄数量的限制,修改/etc/security/limits.conf文件即可。