nginx在linux为何效率高
答案:采用epoll的事件模型。
首先nginx支持一下這些事件模型(參考nginx的wiki)
Nginx支持如下處理連接的方法(I/O復用方法),這些方法可以通過use指令指定。
- select?– 標準方法。 如果當前平臺沒有更有效的方法,它是編譯時默認的方法。你可以使用配置參數(shù)?–with-select_module?和?–without-select_module?來啟用或禁用這個模塊。
- poll?– 標準方法。 如果當前平臺沒有更有效的方法,它是編譯時默認的方法。你可以使用配置參數(shù)?–with-poll_module?和?–without-poll_module?來啟用或禁用這個模塊。
- kqueue?– 高效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用雙處理器的MacOS X系統(tǒng)使用kqueue可能會造成內(nèi)核崩潰。
- epoll?– 高效的方法,使用于Linux內(nèi)核2.6版本及以后的系統(tǒng)。在某些發(fā)行版本中,如SuSE 8.2, 有讓2.4版本的內(nèi)核支持epoll的補丁。
- rtsig?– 可執(zhí)行的實時信號,使用于Linux內(nèi)核版本2.2.19以后的系統(tǒng)。默認情況下整個系統(tǒng)中不能出現(xiàn)大于1024個POSIX實時(排隊)信號。這種情況對于高負載的服務(wù)器來說是低效的;所以有必要通過調(diào)節(jié)內(nèi)核參數(shù)/proc/sys/kernel/rtsig-max?來增加隊列的大小。可是從Linux內(nèi)核版本2.6.6-mm2開始, 這個參數(shù)就不再使用了,并且對于每個進程有一個獨立的信號隊列,這個隊列的大小可以用 RLIMIT_SIGPENDING 參數(shù)調(diào)節(jié)。當這個隊列過于擁塞,nginx就放棄它并且開始使用?poll?方法來處理連接直到恢復正常。
- /dev/poll?– 高效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
- eventport?– 高效的方法,使用于 Solaris 10. 為了防止出現(xiàn)內(nèi)核崩潰的問題, 有必要安裝?這個?安全補丁。
在linux下面,只有epoll是高效的方法。
下面再來看看epoll到底是如何高效的
Epoll是Linux內(nèi)核為處理大批量句柄而作了改進的poll。要使用epoll只需要這三個系統(tǒng)調(diào)用:epoll_create(2), epoll_ctl(2), epoll_wait(2)。它是在2.5.44內(nèi)核中被引進的(epoll(4) is a new API introduced in Linux kernel 2.5.44),在2.6內(nèi)核中得到廣泛應用。
epoll的優(yōu)點
- 支持一個進程打開大數(shù)目的socket描述符(FD)
select 最不能忍受的是一個進程所打開的FD是有一定限制的,由FD_SETSIZE設(shè)置,默認值是2048。對于那些需要支持的上萬連接數(shù)目的IM服務(wù)器來說顯然太少了。這時候你一是可以選擇修改這個宏然后重新編譯內(nèi)核,不過資料也同時指出這樣會帶來網(wǎng)絡(luò)效率的下降,二是可以選擇多進程的解決方案(傳統(tǒng)的Apache方案),不過雖然linux上面創(chuàng)建進程的代價比較小,但仍舊是不可忽視的,加上進程間數(shù)據(jù)同步遠比不上線程間同步的高效,所以也不是一種完美的方案。不過 epoll則沒有這個限制,它所支持的FD上限是最大可以打開文件的數(shù)目,這個數(shù)字一般遠大于2048,舉個例子,在1GB內(nèi)存的機器上大約是10萬左右,具體數(shù)目可以cat /proc/sys/fs/file-max察看,一般來說這個數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大。
- IO效率不隨FD數(shù)目增加而線性下降
傳統(tǒng)的select/poll另一個致命弱點就是當你擁有一個很大的socket集合,不過由于網(wǎng)絡(luò)延時,任一時間只有部分的socket是”活躍”的,但是select/poll每次調(diào)用都會線性掃描全部的集合,導致效率呈現(xiàn)線性下降。但是epoll不存在這個問題,它只會對”活躍”的socket進行操作—這是因為在內(nèi)核實現(xiàn)中epoll是根據(jù)每個fd上面的callback函數(shù)實現(xiàn)的。那么,只有”活躍”的socket才會主動的去調(diào)用 callback函數(shù),其他idle狀態(tài)socket則不會,在這點上,epoll實現(xiàn)了一個”偽”AIO,因為這時候推動力在os內(nèi)核。在一些 benchmark中,如果所有的socket基本上都是活躍的—比如一個高速LAN環(huán)境,epoll并不比select/poll有什么效率,相反,如果過多使用epoll_ctl,效率相比還有稍微的下降。但是一旦使用idle connections模擬WAN環(huán)境,epoll的效率就遠在select/poll之上了。
- 使用mmap加速內(nèi)核與用戶空間的消息傳遞。
這點實際上涉及到epoll的具體實現(xiàn)了。無論是select,poll還是epoll都需要內(nèi)核把FD消息通知給用戶空間,如何避免不必要的內(nèi)存拷貝就很重要,在這點上,epoll是通過內(nèi)核于用戶空間mmap同一塊內(nèi)存實現(xiàn)的。而如果你想我一樣從2.5內(nèi)核就關(guān)注epoll的話,一定不會忘記手工 mmap這一步的。
- 內(nèi)核微調(diào)
這一點其實不算epoll的優(yōu)點了,而是整個linux平臺的優(yōu)點。也許你可以懷疑linux平臺,但是你無法回避linux平臺賦予你微調(diào)內(nèi)核的能力。比如,內(nèi)核TCP/IP協(xié)議棧使用內(nèi)存池管理sk_buff結(jié)構(gòu),那么可以在運行時期動態(tài)調(diào)整這個內(nèi)存pool(skb_head_pool)的大小— 通過echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函數(shù)的第2個參數(shù)(TCP完成3次握手的數(shù)據(jù)包隊列長度),也可以根據(jù)你平臺內(nèi)存大小動態(tài)調(diào)整。更甚至在一個數(shù)據(jù)包面數(shù)目巨大但同時每個數(shù)據(jù)包本身大小卻很小的特殊系統(tǒng)上嘗試最新的NAPI網(wǎng)卡驅(qū)動架構(gòu)。
轉(zhuǎn)載于:https://blog.51cto.com/lya041/731018
總結(jié)
以上是生活随笔為你收集整理的nginx在linux为何效率高的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文件夹和文件的名称变成蓝色
- 下一篇: Linux 自动删除N天前的文件