日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747



Nginx現在是非常火爆的web服務器,她使用更少的資源,支持更多的并發連接數,實現了linux的epoll模型。

Nginx采用的是多進程單線程和多路IO復用模型。使用了I/O多路復用技術的Nginx,就成了”并發事件驅動“的服務器。這里再強調下重點,

  • 多進程單線程
  • 多路IO復用模型
搞定Nginx高并發原理:多進程單線程和多路IO復用模型

 

一、多進程單線程

Nginx 自己實現了對epoll的封裝,是多進程單線程的典型代表。使用多進程模式,不僅能提高并發率,而且進程之間是相互獨立的,一 個worker進程掛了不會影響到其他worker進程。

master進程管理worker進程:

  1. 接收來自外界的信號。
  2. 向各worker進程發送信號。
  3. 監控woker進程的運行狀態。
  4. 當woker進程退出后(異常情況下),會自動重新啟動新的woker進程。

注意worker進程數,一般會設置成機器cpu核數。因為更多的worker只會導致進程之間相互競爭cpu,從而帶來不必要的上下文切換。
 

二、IO 多路復用模型 epoll

多路復用,允許我們只在事件發生時才將控制返回給程序,而其他時候內核都掛起進程,隨時待命。

epoll通過在Linux內核中申請一個簡易的文件系統(文件系統一般用B+樹數據結構來實現),其工作流程分為三部分:

  1. 調用 int epoll_create(int size)建立一個epoll對象,內核會創建一個eventpoll結構體,用于存放通過epoll_ctl()向epoll對象中添加進來的事件,這些事件都會掛載在紅黑樹中。
  2. 調用 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 在 epoll 對象中為 fd 注冊事件,所有添加到epoll中的事件都會與設備驅動程序建立回調關系,也就是說,當相應的事件發生時會調用這個sockfd的回調方法,將sockfd添加到eventpoll 中的雙鏈表。
  3. 調用 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 來等待事件的發生,timeout 為 -1 時,該調用會阻塞知道有事件發生。

注冊好事件之后,只要有fd上事件發生,epoll_wait()就能檢測到并返回給用戶,用戶執行阻塞函數時就不會發生阻塞了。

epoll()在中內核維護一個鏈表,epoll_wait直接檢查鏈表是不是空就知道是否有文件描述符準備好了。順便提一提,epoll與select、poll相比最大的優點是不會隨著sockfd數目增長而降低效率,使用select()時,內核采用輪訓的方法來查看是否有fd準備好,其中的保存sockfd的是類似數組的數據結構fd_set,key 為 fd,value為0或者1(發生時間)。

能達到這種效果,是因為在內核實現中epoll是根據每 sockfd 上面的與設備驅動程序建立起來的回調函數實現的。那么,某個sockfd上的事件發生時,與它對應的回調函數就會被調用,將這個sockfd加入鏈表,其他處于“空閑的”狀態的則不會。在這點上,epoll 實現了一個"偽"AIO。

可以看出,因為一個進程里只有一個線程,所以一個進程同時只能做一件事,但是可以通過不斷地切換來“同時”處理多個請求。

例子:Nginx 會注冊一個事件:“如果來自一個新客戶端的連接請求到來了,再通知我”,此后只有連接請求到來,服務器才會執行 accept() 來接收請求。又比如向上游服務器(比如 php-FPM)轉發請求,并等待請求返回時,這個處理的 worker 不會在這阻塞,它會在發送完請求后,注冊一個事件:“如果緩沖區接收到數據了,告訴我一聲,我再將它讀進來”,于是進程就空閑下來等待事件發生。

這樣,基于 多進程+epoll, Nginx 便能實現高并發。

 

三、worker進程工作流程

當一個 worker 進程在 accept() 這個連接之后,就開始讀取請求,解析請求,處理請求,產生數據后,再返回給客戶端,最后才斷開連接,一個完整的請求。一個請求,完全由worker進程來處理,而且只會在一個worker進程中處理。優點:

  1. 節省鎖帶來的開銷。每個worker進程都彼此獨立地工作,不共享任何資源,因此不需要鎖。同時在編程以及問題排查上時,也會方便很多。
  2. 獨立進程,減少風險。采用獨立的進程,可以讓互相之間不會影響,一個進程退出后,其它進程還在工作,服務不會中斷,master進程則很快重新啟動新的worker進程。當然,worker進程自己也能發生意外退出。

四、對驚群效應的處理

Nginx提供了一個accept_mutex這個東西,這是一個加在accept上的一把互斥鎖。即每個worker進程在執行accept()之前都需要先獲取鎖,accept()成功之后再解鎖。有了這把鎖,同一時刻,只會有一個進程執行accpet(),這樣就不會有驚群問題了。accept_mutex是一個可控選項,我們可以顯示地關掉,默認是打開的。

分享到:
標簽:并發 Nginx
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定