附:Nginx配置檔案nginx.conf中文詳解

鄔興亮發表於2016-11-24

nginx是什麼?

  nginx是一個強大的web伺服器軟體,用於處理高併發的http請求和作為反向代理伺服器做負載均衡。具有高效能、輕量級、記憶體消耗少,強大的負載均衡能力等優勢。

 

 nginx架構?

  如上官方示意圖所示,nginx啟動以後,會在系統中以daemon的方式在後臺執行,其中包括一個master程式,n(n>=1)個worker程式。

  其中,master程式用於接收來自外界的訊號,並給worker程式傳送訊號,同時監控worker程式的工作狀態。

       worker程式則是外部請求真正的處理者,每個worker請求相互獨立且平等的競爭來自客戶端的請求。請求只能在一個worker程式中被處理,且一個worker程式只有一個主執行緒,所以同時只能處理一個請求。那麼問題來了,一個worker程式只有一個主執行緒,只能同時處理一個請求,nginx對高併發請求強大的處理能力是如何保證的呢?答案是nginx採用非同步非阻塞的方式來處理請求,即單執行緒、非阻塞、非同步IO的工作模型。對比apache的非同步非阻塞版本的工作模式,apache會為每一個請求新建一個執行緒去處理請求,執行緒進行上下文切換,會造成記憶體和CPU的浪費。反看nginx的非同步非阻塞io模式,實用作業系統提供的io多路複用技術(epoll),在一個執行緒中處理所有請求,當一個io操作開始的時候,nginx不會等待其完成就回去處理下一個請求,等到io操作完成後,nginx再回來處理這一次請求io操作的後續工作。相比apache,nginx省去了執行緒上下文切換帶來的資源開銷。 

       那麼nginx如何確定哪個worker來處理請求呢?首先,每個worker程式都是從master程式fork過來,在master程式裡面,先建立好需要listen的socket(listenfd)之後,然後再fork出多個worker程式。所有worker程式的listenfd會在新連線到來時變得可讀,為保證只有一個程式處理該連線,所有worker程式在註冊listenfd讀事件前搶accept_mutex,搶到互斥鎖的那個程式註冊listenfd讀事件,在讀事件裡呼叫accept接受該連線。當一個worker程式在accept這個連線之後,就開始讀取請求,解析請求,處理請求,產生資料後,再返回給客戶端,最後才斷開連線,這樣一個完整的請求就是這樣的了。這樣,一個請求,完全由worker程式來處理,而且只在一個worker程式中處理。

 

 nginx效能?

       這裡援引網上搜尋到的nginx的測試資料:10000個非活躍的HTTP keep-alive 連線僅佔用約2.5MB記憶體。三萬併發連線下,10個Nginx程式,消耗記憶體150M。淘寶tengine團隊說測試結果是“24G記憶體機器上,處理併發請求可達200萬”。

 

 nginx負載均衡?

       通訊協議支援:nginx負載均衡主要是對七層網路通訊模型中的第七層應用層上的http、https進行支援。同時nginx更新版本也在逐步對Websocket、SPDY等協議作出支援。

nginx是以反向代理的方式進行負載均衡的。反向代理(Reverse Proxy)方式是指以代理伺服器來接受Internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給Internet上請求連線的客戶端,此時代理伺服器對外就表現為一個伺服器。(為了理解反向代理,這裡插播一條什麼是正向代理:正向代理指的是,一個位於客戶端和原始伺服器之間的伺服器,為了從原始伺服器取得內容,客戶端向代理傳送一個請求並指定目標(原始伺服器),然後代理向原始伺服器轉交請求並將獲得的內容返回給客戶端。)

       這裡再插播一條實現負載均衡的技術的方式有哪些:硬體層面有F5負載均衡器,網路層層面有LVS(Linux Virtual Server),應用層層面就是nginx、Haproxy等。

       nginx實現負載均衡的分配策略有很多,被編進nginx核心的策略有輪詢和ip_hash,第三方的有fair、url_hash等。這裡主要對核心策略進行介紹。

1.輪詢

  a)none(預設輪詢):upstream按照輪詢(預設)方式進行負載,每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。雖然這種方式簡便、成本低廉。但缺點是:可靠性低和負載分配不均衡。

  b)weight(按權重輪詢):指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況。 

server 192.168.61.22 weight = 6; # 60% 請求
server 192.168.61.23 weight = 4; # 40% 請求

 

2.ip_hash

  每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。配置只需要在upstream中加入"ip_hash;"即可。

upstream tomcats {
      ip_hash;
      server 127.0.0.1:9001;
      server 127.0.0.1:9002;
}

 

3.fair(第三方)

  按後端伺服器的響應時間來分配請求,響應時間短的優先分配。與weight分配策略類似。

upstream tomcats {
      server 127.0.0.1:9001;
      server 127.0.0.1:9002;
      fair;
}

 

4.url_hash(第三方)

  和IP雜湊類似,只不過針對請求的url進行hash(基於快取的server,頁面靜態化)。

 

附:Nginx配置檔案nginx.conf中文詳解

相關文章