导读 | 几日前公司同事王开源同志将笔记本系统转成了liunx系统,看上去不错,应该有的应用基本上都有了。如文档处理软件、表格处理软件、eclipse开发环境等。别说,还真不错。本身又一次动心想装一个liunx系统使用,但是尚未敢这样作,采用linux系统实在是太浪费精力了,不少东西要本身设置。 |
为何Nginx的性能要比Apache高得多?html
这主要是由于Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(FreeBSD)网络I/O模型,而Apache则使用的是传统的select模型。曾在一篇博客上看到有这么个实例:linux
假设你在大学中读书,要等待一个朋友来访,而这个朋友只知道你在A号楼,可是不知道你具体住在哪里,因而大家约好了在A号楼门口见面.若是你使用的阻塞IO 模型来处理这个问题,那么你就只能一直守候在A号楼门口等待朋友的到来,在这段时间里你不能作别的事情,不难知道,这种方式的效率是低下的.如今时代变化了,开始使用多路复用IO模型来处理这个问题.你告诉你的朋友来了A号楼找楼管大妈,让她告诉你该怎么走.这里的楼管大妈扮演的就是多路复用IO的角色。编程
解释select和epoll模型的工做方式:网络
select版大妈作的是以下的事情:好比同窗甲的朋友来了,select版大妈比较笨,她带着朋友挨个房间进行查询谁是同窗甲,你等的朋友来了。若是每到来一个朋友楼管大妈都要全楼的查询同窗,那么处理的效率必然就低下了,过不久楼底就有很多的人了。eclipse
epoll版大妈就比较先进了,她记下了同窗甲的信息,好比说他的房间号,那么等同窗甲的朋友到来时,只须要告诉该朋友同窗甲在哪一个房间便可,不用本身亲自带着人满大楼的找人了。epoll大妈能够不用吹灰之力就能够定位到同窗甲。一看就很明白 epoll和select 模型的区别了吧。socket
在Linux内核中,select所用到的FD_SET是有限的,即内核中有个参数__FD_SETSIZE定义了每一个FD_SET的句柄个数,在内核源码中 /usr/include/linux/posix_types.h 中函数
#undef __FD_SETSIZE #define __FD_SETSIZE 1024
若是想要同时检测1025个句柄的可读状态或 可写状态 ,select是不能实现的。在内核中实现select是使用轮询方法,即每次检测都会遍历全部FD_SET中的句柄,显然,select函数的执行时间与 FD检测的句柄数越多就会越费时。性能
epoll是多路复用IO(I/O Multiplexing) 中的一种方式,仅用于linux2.6以上内核。而epoll模型它所支持的FD上限是最大能够打开文件的数目,这个数字通常远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体请查看:cat /proc/sys/fs/file-max ,这个数目和系统内存关系很大。server
传统的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之上了。htm
epoll有两种工做模式:Edge Triggered (ET)、Level Triggered (LT)
LT(level triggered)是缺省的工做方式,而且同时支持block和no-block socket.在这种作法中,内核告诉你一个文件描述符是否就绪了,而后能够对这个就绪的fd进行IO操做。若是你不做任何操做,内核仍是会继续通知你的,因此,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的表明。
ET (edge-triggered)是高速工做方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核经过epoll告诉你。而后它会假设你知道文件描述符已经就绪,而且不会再为那个文件描述符发送更多的就绪通知,直到你作了某些操做致使那个文件描述符再也不为就绪状态了(好比,你在发送,接收或者接收请求,或者发送接收的数据少于必定量时致使了一个EWOULDBLOCK 错误)。