Nginx--面試基礎必會

逆月翎發表於2019-09-23

文章原創於公眾號:程式猿周先森。本平臺不定時更新,喜歡我的文章,歡迎關注我的微信公眾號。file

最近一直在更新關於Nginx的系列文章,終於將Nginx的幾個關鍵知識點講的差不多了。本篇作為Nginx系列的結尾篇幅,主要是列舉一些面試時經常問到的Nginx知識點。其實Nginx適合提問的面試點並不多,問來問去基本都是類似的問題。接下來我們一起來看看Nginx基本的面試題。

Nginx的作用

這個問題是入門級知識點,討論Nginx的用處。我覺得只要幾個重要的點都回答到位就可以了,可以考慮這樣的一個回答:Nginx是一個高效能web伺服器和反向代理伺服器,也是一個IMAP/POP3/SMTP伺服器。不僅可以實現負載均衡,還可以做介面限流,快取等功能。

使用Nginx的優勢點

  • Nginx由於使用了epoll和kqueue網路I/O模型,在實際生產環境能夠支撐3萬左右併發連線。
  • Nginx記憶體消耗低。
  • Nginx跨平臺,而且配置相對來說難度較低。
  • Nginx內建健康檢查功能,如果負載均衡其中一個伺服器當機了,則接受到的請求會傳送給其他伺服器去處理。
  • 支援Gzip壓縮,可以新增瀏覽器本地快取的Header頭。
  • Nginx支援熱部署,可以在不間斷服務的情況下平滑進行配置的更改。
  • Nginx非同步接收使用者請求,減輕了Web伺服器的壓力。

Nginx如何實現高併發

這個問題出來可能懂一點Nginx的朋友們都是浮現出5個字:非同步非阻塞。實際上Nginx就是非同步非阻塞,使用了epoll模型並對底層程式碼進行大幅度優化。之前其實有講過Nginx是採用1個master程式,多個worker程式的模式,每次接收到一個請求,master會將請求按照一定策略分發給一個worker程式去進行處理請求。worker程式數一般設定為和CPU核心數一致,非同步非阻塞模式就會使得worker執行緒在等待請求callback的空閒時間可以接收處理新的請求,當接收到舊請求的callback時再回去繼續處理該請求,這樣就完成了少數幾個worker程式卻實現了高併發的問題。

Nginx為何不使用多執行緒?

眾所周知,沒建立一個新的執行緒,都需要為其分配cpu和記憶體。當然,建立程式也是一樣,但是由於執行緒過多會導致記憶體消耗過多。所以Nginx採用單執行緒非同步處理使用者請求,這樣不需要不斷地為新的執行緒分配cpu和記憶體,減輕伺服器記憶體消耗,所以使得Nginx效能方面更為高效。

Nginx如何處理請求?

Nginx啟動後,首先進行配置檔案的解析,解析成功會得到虛擬伺服器的ip和埠號,在主程式master程式中建立socket,對addrreuse選項進行設定,並將socket繫結到對應的ip地址和埠並進行監聽。然後建立子程式worker程式,當客戶端和Nginx進行三次握手,則可以建立成功與Nginx的連線。當有新的請求進入時,空閒的worker程式會競爭,當某一個worker程式競爭成功,則會得到這個已經成功建立連線的socket,然後建立ngxconnectiont結構體,接下來設定讀寫事件處理函式並新增讀寫事件用來與客戶端進行資料交換。當請求結束Nginx或者客戶端主動關閉連線,此時一個請求處理完畢。

為什麼要做動靜分離?

在日常開發中,前端請求靜態檔案比如圖片資源是不需要經過後端伺服器的,但是呼叫API這些型別的就需要後端進行處理請求,所以為了提高對資原始檔的響應速度,我們應該使用動靜分離的策略去做架構。我們可以將靜態檔案放到Nginx中,將動態資源的請求轉發到後端伺服器去進行進一步的處理。

Nginx負載均衡的幾種常用方式?

輪詢方式:預設情況下Nginx使用輪詢的方式實現負載均衡,每個新的請求按照時間順序逐一分配到不同的後端伺服器去進行處理,如果後端伺服器當機,則Nginx的健康檢查功能會將這個後端伺服器剔除。但是輪詢方式是顯而易見的:可靠性低而且負載分配不平衡,所以輪詢方式更適用於圖片伺服器或者靜態資源伺服器。

  • weight:可以對不同的後端伺服器設定不同的權重比例,這樣可以改變不同後端伺服器處理請求的比例。可以給效能更優的後端伺服器配置更高的權重。
  • ip_hash:這種方式會根據請求的ip地址的hash結果分配後端伺服器來處理請求,這樣每個使用者發起的請求固定只會由同一個後端伺服器處理,這樣可以解決session問題。
  • fail:這種方式有點類似於輪詢方式,主要是根據後端伺服器的響應時間來分配請求,響應時間短的後端伺服器優先分配請求。
  • url_hash:這種方式是按照請求url的hash結果來將不同請求分配到不同伺服器,使用這種方式每個url的請求都會由同一個後端伺服器進行處理,後端伺服器為快取時效率會更高。

Session不同步如何處理?

上面其實提過了解決方案,負載均衡方式使用ip_hash方式,如果使用者已經訪問過某個後端器,則再次訪問時會將這個請求的ip地址進行雜湊演算法轉換,自動定位到該伺服器。當然也可以通過redis快取使用者session,一樣可以處理session不同步的問題。

Nginx常用優化配置

  1. 調整worker_processes指定Nginx需要建立的worker程式數量,剛才有提到worker程式數一般設定為和CPU核心數一致。
  2. 調整workerconnections設定Nginx最多可以同時服務的客戶端數。結合workerprocesses配置可以獲得每秒可以服務的最大客戶端數。
  3. 啟動gzip壓縮,可以對檔案大小進行壓縮,減少了客戶端http的傳輸頻寬,可以大幅度提高頁面的載入速度。
  4. 啟用快取,如果請求靜態資源,啟用快取是可以大幅度提升效能的。關於啟用快取可以觀看Nginx快取這篇文章:Nginx快取原理及機制

Nginx正向代理

正向代理也是大家最常接觸的到的代理模式,那究竟什麼是正向代理呢?我們都知道Google在國內是無法正常訪問的,但是某些時候我們由於技術問題需要去訪問Google時,我們會先找到一個可以訪問Google的代理伺服器,我們將請求傳送到代理伺服器,代理伺服器去訪問Google,然後將訪問到的資料返回給我們,這樣的過程就是正向代理。正向代理最大的特點是客戶端需要明確知道要訪問的伺服器地址,Google伺服器只清楚請求來自哪個代理伺服器,而不清楚來自哪個具體的客戶端,正向代理可以隱藏真實客戶端的具體資訊。file

客戶端必須設定正向代理伺服器,而且需要知道正向代理伺服器的IP地址以及代理程式的埠。一句話來概括就是正向代理代理的是客戶端,是一個位於客戶端和Google伺服器之間的伺服器,為了從Google伺服器取得資料,客戶端向代理伺服器傳送一個請求並指定目標(Google伺服器),然後代理向原始伺服器轉交請求並將獲得的資料返回給客戶端。總結正向代理的幾個作用:

  • 訪問國外無法訪問的網站做快取,加速訪問資源
  • 對客戶端訪問授權,上網進行認證代理
  • 可以記錄使用者訪問記錄(上網行為管理),對外隱藏使用者資訊

Nginx反向代理

多個客戶端給伺服器傳送的請求,Nginx伺服器接收到請求以後,按照一定的規則轉發到不同的伺服器進行業務邏輯處理,也就是我們剛才講到的負載均衡的策略。此時請求來源於哪個客戶端是確定的,但是請求由哪臺伺服器處理的並不明確,Nginx扮演的就是一個反向代理角色。可以這樣來理解,反向代理對外都是透明的,訪問者並不知道自己訪問的是一個代理。反向代理代理的是服務端,主要用於伺服器叢集分散式部署的情況下,反向代理隱藏了伺服器的資訊。總結下反向代理的兩個作用:

  • 保證內網的安全,通常將反向代理作為公網訪問地址,Web伺服器是內網
  • 負載均衡,通過反向代理伺服器來優化網站的負載

Nginx中正向代理與反向代理的區別file

  1. 在正向代理中,隱藏了請求來源的客戶端資訊;
  2. 在反向代理中,隱藏了請求具體處理的服務端資訊;

歡迎關注我的個人公眾號:程式猿周先森file

相關文章