`
lelong
  • 浏览: 553916 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JAVA使用EPoll来进行NIO处理的方法(转)

 
阅读更多

JDK 6.0 以及JDK 5.0 update 9 的 nio支持epoll (仅限 Linux 系统 ),对并发idle connection会有大幅度的性能提升,这就是很多网络服务器应用程序需要的。

启用的方法如下:

-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider  
 

例如在 Linux 下运行的 Tomcat 使用 NIO Connector ,那么启用 epoll 对性能的提升会有帮助。

而 Tomcat 要启用这个选项的做法是在 catalina.sh 的开头加入下面这一行

CATALINA_OPTS='-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider'

Epoll是Linux内核为处理大批量句柄而作了改进的poll。要使用epoll只需要这三个系统调用:epoll_create(2), epoll_ctl(2), epoll_wait(2)。它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44),在2.6内核中得到广泛应用,例如LightHttpd

 

 

一 epoll - 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加速内核与用户空间的消息传递。

这点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注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 - epoll的使用

 

令人高兴的是,2.6内核的epoll比其2.5开发版本的/dev/epoll简洁了许多,所以,大部分情况下,强大的东西往往是简单的。唯一有点麻烦是epoll有2种工作方式:LT和ET。

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原理和使用

    Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能...通过仔细阅读这个例程,相信你已经大致了解NIO的原理和使用方法,下一篇,我们将使用多线程来处理这些数据,再搭建一个自己的Reactor模式。

    高手使用Java NIO编写高性能的服务器

    Java NIO(New IO)是Java 1.4版本引入的一个新特性,它为Java程序提供了非阻塞I/O操作的能力,极大地提升了Java在处理网络通信和文件读写时的性能。NIO与传统的IO( Blocking IO)模型相比,最大的区别在于其非阻塞...

    Java NIO——Selector机制解析三(源码分析)

    Java NIO的Selector实现主要由`sun.nio.ch.SelectorImpl`类完成,其内部使用了操作系统提供的多路复用I/O机制,如Linux的epoll、Windows的IOCP等。`select()`方法实际上会调用操作系统API,阻塞等待直到有事件发生。...

    NIO 入门.chm,NIO 入门.chm

    **NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...

    Reilly__Java_NIO英文版和中文版

    NIO在Java 1.4版本中引入,为高性能、并发I/O处理提供了新的解决方案。Reilly的《Java NIO》是一本权威的指南,深入介绍了这一强大的技术。 该书英文版和中文版的提供,对于学习和理解Java NIO具有很大的帮助。英文...

    3种下载文件程序的思考,为何使用NIO进行异步网络通讯

    标题中的“3种下载文件程序的思考,为何使用NIO进行异步网络通讯”提示了我们探讨的主题,即网络通信中的不同下载策略以及为何选择非阻塞I/O(Non-blocking I/O, NIO)作为异步通信的方式。在这个话题中,我们将深入...

    基于Java NIO的网络编程框架.zip

    本项目深入探讨了Java网络编程中的多种模式,包括BIO(阻塞IO)、NIO(非阻塞IO)、IO多路复用(select、poll、epoll)、Reactor模式,以及零拷贝技术。通过这些实现,项目展示了如何在高并发环境下优化网络通信效率...

    tomcat:Java使用nio模式实现tomcat

    Java NIO(New IO)是Java 1.4版本引入的一种新的I/O API,它提供了非阻塞I/O操作的能力,极大地提升了Java处理网络通信的能力。在Tomcat服务器的实现中,NIO模式被用来提高其性能和并发能力,尤其是在高并发场景下...

    javaNIO学习笔记(csdn)————程序.pdf

    5. Reactor调用相应事件处理器的方法来处理事件。 6. 事件处理器执行具体的业务逻辑。 NIO通过非阻塞的特性,结合选择器和事件驱动的机制,使得Java程序能够高效地处理大量并发的I/O操作,特别适合构建高性能的网络...

    解读NIOSELECTEpoll思想 P8专家级面试题你也能听懂

    NIO是Java提供的一种用于处理网络I/O的方式,其核心在于能够使用较少的线程来处理大量的网络连接。SELECT和Epoll是两种I/O复用技术,允许单个线程监视多个文件描述符,从而实现对多个网络连接的有效管理。 在James...

    深度剖析jvm+nio

    而NIO(Non-blocking Input/Output)是Java提供的一种I/O模型,与传统的阻塞I/O模型(BIO)相对,极大地提高了程序在处理大量并发连接时的效率。阿里巴巴的扫地僧多隆,以其深厚的Java技术底蕴,为我们带来了关于JVM...

    java物联网源码-IOtest:JavaNIO与linuxepoll和WindowsAysnchronous之间的一些测试程序,带有源代码视

    源代码视图提供了深入理解这些测试细节的机会,包括如何设置和使用Java NIO的Selector、Channel和Buffer,如何与epoll或Windows异步I/O接口交互,以及如何收集和分析性能数据。通过分析和修改这些源代码,开发者可以...

    NIO trick and trap .pdf

    - **ByteBuffer的选择**:根据应用场景选择合适的`ByteBuffer`类型,如使用`DirectByteBuffer`来减少数据复制。 - **ViewByteBuffer**:提供视图,允许共享相同的底层缓冲区数据,提高效率。 - **FileChannel....

    Java IO应届生培训讲义

    综上所述,Java IO培训讲义通过系统介绍Java IO的基本概念和模型,帮助应届生理解并掌握Java IO类库的使用,特别是在了解和应用不同IO模型时的注意事项和实践方法。通过这份讲义,初学者能更好地理解和编写涉及Java ...

    Netty应用说明笔记

    4. 操作系统兼容性:Netty针对不同操作系统进行了优化,特别是对Linux内核的epoll事件模型,解决了Java NIO中的poll/epoll bug,降低了CPU使用率。 不选择Netty 5的原因可能包括: 1. ForkJoinPool带来的复杂性:...

    Java面经.适用于校招

    Java基础部分包括了对Java语言的核心概念和使用方法的介绍。 1.1 Java的8种基本数据类型装箱拆箱 - 8种基本数据类型包括:byte、short、int、long、float、double、char和boolean。 - 装箱是将基本数据类型封装到...

    异步通信核心简单实现(Java)

    本主题将深入探讨如何使用Java的非阻塞I/O(Non-blocking Input/Output,NIO)包来实现一个简单的异步通信核心,重点关注NIO中的通道(Channel)、通道选择器(Selector)和选择器键(Selector Key)。 1. **Java ...

    Scalable IO in Java

    总结来说,Scalable IO in Java涉及多个层次,从基础IO流的优化到NIO和NIO.2的使用,再到并发策略和流式API的集成,这些都是提升Java应用程序在处理大量数据时性能和可扩展性的关键要素。理解并熟练运用这些技术,...

    传统BIO编程模型及NIO编程模型源码

    Netty使用了高级的NIO特性,如epoll和kqueue,提供了更高效的性能和更好的可扩展性。 在Netty中,BIO和NIO的源码分析可以帮助我们深入了解底层的I/O机制,理解如何通过Java API实现高效的网络通信。学习这些源码...

Global site tag (gtag.js) - Google Analytics