在JDK5U9之后,NIO在Linux 内核版本大于2.6的服务器上支持了epoll。其对并发的处理会有大幅度的性能提升,JVM启动参数如下:
-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider
在tomcat中启用的办法是在 catalina.sh 的开头加入下面这一行:
CATALINA_OPTS='-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider'
Epoll的优点有哪些呢?
- 支持一个进程打开大数目的socket描述符(FD)
select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
- IO效率不随FD数目增加而线性下降
传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是"活跃"的,但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对"活跃"的socket进行操作---这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有"活跃"的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个"伪"AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的---比如一个高速LAN环境,epoll并不比select/poll有什么效率,相反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。
- 使用mmap加速内核与用户空间的消息传递。
无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。
- 内核微调
这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。比如,内核TCP/IP协议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小--- 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。
Epoll的工作方式
- LT(level triggered) 缺省的工作方式,同时支持block和no-block socket.
在这种模式下,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表.
- ET (edge-triggered) 高速工作方式,只支持no-block socket.
在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once),不过在TCP协议中,ET模式的加速效用仍需要更多的benchmark确认。
epoll只有epoll_create,epoll_ctl,epoll_wait 3个系统调用,
具体用法请参考http://www.xmailserver.org/linux-patches/nio-improve.html
在http://www.kegel.com/rn/有一个完整的例子。
相关推荐
Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,...
4. **多路复用器(Multiplexing)**:Java NIO的多路复用器基于操作系统提供的Select或Poll机制,如Linux下的epoll。它能有效地监控大量通道的状态,提高系统资源利用率。 5. **文件系统访问**:NIO也提供了对文件...
Java NIO的Selector实现主要由`sun.nio.ch.SelectorImpl`类完成,其内部使用了操作系统提供的多路复用I/O机制,如Linux的epoll、Windows的IOCP等。`select()`方法实际上会调用操作系统API,阻塞等待直到有事件发生。...
Java NIO,全称为Non-Blocking Input/Output,是Java平台中用于替代标准阻塞式I/O(BIO)的库。NIO在Java 1.4版本中引入,为高性能、并发I/O处理提供了新的解决方案。Reilly的《Java NIO》是一本权威的指南,深入...
本项目深入探讨了Java网络编程中的多种模式,包括BIO(阻塞IO)、NIO(非阻塞IO)、IO多路复用(select、poll、epoll)、Reactor模式,以及零拷贝技术。通过这些实现,项目展示了如何在高并发环境下优化网络通信效率...
本项目"IOtest"是针对Java NIO在不同操作系统环境下性能对比的一个测试程序,主要关注的是Java NIO与Linux的epoll机制以及Windows的异步I/O之间的差异。Linux的epoll是专门为高并发、高性能网络服务设计的I/O多路...
**NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...
Java NIO,全称Non-Blocking Input/Output,是非阻塞式输入输出,它是Java从1.4版本开始引入的一种新的I/O模型,为Java程序员提供了处理I/O操作的新方式。NIO的主要特点是其能够使Java程序以更有效的方式处理I/O流,...
- **Spring 5.x**:引入了 Flux API,并且完全放弃了 Tomcat,转而使用 Netty 作为服务器端。 - **Zookeeper**:分布式协调服务。 这些框架之所以选择 Netty,主要是因为其在网络通信方面提供了高性能、高可靠性的...
包括同步阻塞IO(BIO)、同步非阻塞IO(NIO)、异步非阻塞IO(AIO)和Linux下的select、epoll等多路复用机制。 11. **异常处理**: Java的异常处理包括try-catch块以及异常类型分类,如checked异常和unchecked异常。 ...
9. **NIO 和 EPOLL**:Netty 可以利用 Java NIO 或者 Linux 的 EPOLL(在其他平台上也有相应的选择),提供高性能的非阻塞 I/O。 10. **线程模型**:Netty 的线程模型设计得很灵活,可以根据需求选择单线程、多线程...
Java NIO(New IO)是Java 1.4版本引入的一种新的I/O API,它提供了非阻塞I/O操作的能力,极大地提升了Java处理网络通信的能力。在Tomcat服务器的实现中,NIO模式被用来提高其性能和并发能力,尤其是在高并发场景下...
Java NIO(New I/O)和Node.js 是两种高性能IO技术,它们之所以能够实现高性能的IO操作,离不开底层操作系统的支持。本文将详细探讨支撑Java NIO和Node.js的底层技术,包括各种I/O模型的原理和区别,以及同步、异步...
4. 操作系统兼容性:Netty针对不同操作系统进行了优化,特别是对Linux内核的epoll事件模型,解决了Java NIO中的poll/epoll bug,降低了CPU使用率。 不选择Netty 5的原因可能包括: 1. ForkJoinPool带来的复杂性:...
**NIO**(New I/O)是Java为提高I/O操作效率而引入的新特性,最初在JDK 1.4版本中作为JSR 51规范的一部分被提出。随着技术的发展,在JDK 7中进一步扩展为NIO 2(JSR 203),引入了更多高级功能,如文件锁定、原子...
9. **NIO和EPOLL**: Netty支持两种不同的事件模型,Java NIO和Epoll (仅限于Linux)。Epoll提供更好的性能和更低的延迟,尤其是在高并发场景下。 10. **Future和Promise**: Netty使用Future和Promise来处理异步操作...
Java IO应届生培训讲义是一份面向刚毕业的大学生进行Java IO相关知识的培训资料,它涵盖了Java IO的基础知识、不同的IO模型以及Java中的BIO、NIO和AIO高级IO类库。下面详细解释这些知识点: 1. 用户空间和内核空间 ...
1.19 IO、NIO、BIO、AIO、select、epoll - IO(阻塞IO)、NIO(非阻塞IO)、BIO(同步IO)、AIO(异步IO)是不同类型的输入输出操作。 - select和epoll是用于监视多个文件描述符的事件驱动机制。 1.19.1 NIO的原理 ...
- **Java NIO的问题**:虽然Java NIO相比传统的阻塞IO有了很大的改进,但在实际使用过程中仍存在一些问题,例如Epoll错误或内存泄漏等问题。 - **Netty的解决方案**:Netty通过对NIO的深入优化和封装,解决了Java ...