淺析Linux服務器網絡開發模型

導讀 幾日前公司同事王開源同志將筆記本系統轉成了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 錯誤)。

原文來自: https://www.linuxprobe.com/linux-server.html

相關文章
相關標籤/搜索