Apache select與Nginx epoll——“結構決定功能”

Nginx 也許大家的都不陌生,性能好,比起Apache 在域名(domains)、活躍站點、面向 Web 的計算機以及百萬 TOP 站上Apache 依然保持領先,然而,其份額在所有的統計指標上仍在不斷下降。雖然下滑速度較為緩慢,但已持續多月,後續走勢不被看好。

Apache select與Nginx epoll——“結構決定功能”

可能大家看了市場份額會覺得還落後微軟,Apache ,讓小編慢慢來細說來!

Nginx畢竟是後起之秀,還是佔領了將近22%的份額,還在攀升!沒有一個像iis一樣有一個微

軟一樣的“爸爸”,也沒有像Apache一樣,出生好,世界第一軟件品牌孵化出的項目。

後起Nginx得益於使用了最新的epoll(Linux 2.6內核)和kqueue(freebsd)網絡I/O模型, 而

Apache則使用的是傳統的select模型。 目前Linux下能夠承受高併發訪問的Squid、

Memcached都採用的是epoll網絡I/O模型。 處理大量的連接的讀寫,Apache所採用的select

網絡I/O模型非常低效!

下面用一個比喻來解析Apache採用的select模型和Nginx採用的epoll模型進行之間的區別:

假設你在用mysql查詢數據庫使用select查詢數據時,Apache是沒有帶id索引,而Nginx建了

索引,數據量小的時候都差不多,感覺不出來,然後數據量大的時候就慢慢表現出來,帶索引

特別快!

同理,在高併發服務器中,輪詢I/O是最耗時間的操作之一,select和epoll的性能誰的性能更高,同

樣十分明瞭。

重點來說一下epoll

epoll的接口非常簡單,一共就三個函數:

1. int epoll_create(int size);

創建一個epoll的句柄,size用來告訴內核這個監聽的數目一共有多大。

這個參數不同於select()中的第一個參數,給出最大監聽的fd+1的值。

需要注意的是,當創建好epoll句柄後,它就是會佔用一個fd值,在linux下如果查看/proc/進程id/fd/,

是能夠看到這個fd的,所以在使用完epoll後,必須調用close()關閉,否則可能導致fd被耗盡。

2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll的事件註冊函數,它不同與select()是在監聽事件時告訴內核要監聽什麼類型的事件,

而是在這裡先註冊要監聽的事件類型。第一個參數是epoll_create()的返回值,

3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

等待事件的產生,類似於select()調用。

參數events用來從內核得到事件的集合,maxevents告之內核這個events有多大,

這個 maxevents的值不能大於創建epoll_create()時的size,

參數timeout是超時時間(毫秒,0會立即返回,-1將不確定,也有說法說是永久阻塞)。

該函數返回需要處理的事件數目,如返回0表示已超時

其實這三個函數為epoll原理準備的還是貼張圖吧!

Apache select與Nginx epoll——“結構決定功能”

Nginx epoll

至於Apache select 工作原理就比較複雜啦,模式也比較多!還是簡單貼張圖吧

Apache select與Nginx epoll——“結構決定功能”

Apache select

Apache性能沒有Nginx高的原因就是這樣設計理念不同!“結構決定功能 功能決定結構”

想多瞭解每天使用的軟件大家還是要好好的去看設計,看源代碼,勿在浮沙築高臺!!


分享到:


相關文章: