nginx相關知識點總結分享

小云云
發布: 2023-03-22 21:28:02
原創
1446 人瀏覽過

Nginx本身不會對PHP進行解析,終端對PHP頁面的請求將會被Nginx交給FastCGI進程監聽的IP位址及端口,由php-fpm作為動態解析伺服器處理,最後將處理結果再返回給nginx。其實,Nginx就是一個反向代理伺服器。 Nginx透過反向代理功能將動態請求轉向後端php-fpm,從而實現對PHP的解析支持,這就是Nginx實現PHP動態解析的原理。  

     Nginx不支援外部程式的直接呼叫或解析,所有的外部程式(包括PHP)必須透過FastCGI介面來呼叫。 FastCGI介面在Linux下是socket(這個socket可以是檔案socket,也可以是ip socket)。為了呼叫CGI程序,還需要一個FastCGI的wrapper(wrapper可以理解為用於啟動另一個程式的程式),這個wrapper綁定在某個固定socket上,例如連接埠或檔案socket。當Nginx將CGI請求發送給這個socket的時候,透過FastCGI接口,wrapper接收到請求,然後派生出一個新的線程,這個線程調用解釋器或者外部程序處理腳本並讀取返回數據;接著,wrapper再將傳回的資料透過FastCGI接口,沿著固定的socket傳遞給Nginx;最後,Nginx將傳回的資料傳送給客戶端。

經典的模型就是Nginx中所使用的Master-Worker多進程非同步驅動模型。

父進程創建socket,bind、listen後,透過fork創建多個子進程,每個子進程繼承了父進程的socket,呼叫accpet開始監聽等待網路連線。這時候有多個進程同時等待網路的連線事件,當這個事件發生時,這些進程被同時喚醒,就是「驚群」。進程被喚醒,需要進行內核重新調度,這樣每個進程同時去響應這一個事件,而最終只有一個進程能處理事件成功,其他的進程在處理該事件失敗後重新休眠或其他。

其實在Linux2.6版本以後,核心核心已經解決了accept()函數的「驚群」問題,當核心接收到一個客戶連線後,只會喚醒等待佇列上的第一個行程或線程。

Nginx中使用accept_mutexmutex互斥鎖解決這個問題,具體措施有使用全域互斥鎖,每個子程序在epoll_wait()之前先去申請鎖,申請到則繼續處理,獲取不到則等待,並設定了一個負載平衡的演算法(當某一個子程序的任務量達到總設定量的7/8時,則不會再嘗試去申請鎖)來平衡各個行程的任務量。

現在我們對驚群及 Nginx 的處理總結如下:

  • accept 不會有驚群,epoll_wait 才會。

  • Nginx 的 accept_mutex,並不是解決 accept 驚群問題,而是解決 epoll_wait 驚群問題。

  • 說Nginx 解決了 epoll_wait 驚群問題,也是不對的,它只是控制是否將監聽套接字加入到epoll 中。監聽套接字只在一個子進程的 epoll 中,當新的連線來到時,其他子進程當然不會驚醒了。

簡單了說,就是同一時刻只允許一個nginx worker在自己的epoll中處理監聽句柄。它的負載平衡也很簡單,當達到最大connection的7/8時,本worker不會去試圖拿accept鎖,也不會去處理新連接,這樣其他nginx worker進程就更有機會去處理監聽句柄,建立新連線了。而且,由於timeout的設定,使得沒有拿到鎖的worker進程,去拿鎖的頻繁更高。

nginx 多進程模型真的沒有鎖了嗎?其實還是有一個的:ngx_accept_mutex。

nginx是一個多進程程序,80埠為各worker進程共享,每當有連線到來時,勢必多個worker進程都要爭著去回應,這也就是所謂的驚群現象。

當核心accept一個連結時,會喚醒所有等待中的進程,但實際上只有一個進程能獲取連接,其它的進程都被無效喚醒,這種無效喚醒無疑將會增加應用的開銷。為此,nginx提供了一把accept鎖避免九子奪嫡的悲劇。

ngx_accept_mutex的作用也就是讓那些當前負載嚴重

的worker進程主動放棄對新到來的請求的處理,提高

應用整體的喚醒效率,進而提升應用的整體性能。

proxy_cache

upstream

fastcgi_pass

location

非標準狀態碼444表示關閉連線且不給客戶端發送回應頭。

nginx -s  reload 指令載入修改後的設定檔,指令下達後發生下列事件

1. Nginx的master進程檢查設定檔的正確性,若是錯誤則回傳錯誤訊息,nginx繼續採用原始設定檔進行工作(因為worker未受到影響)

##2. Nginx啟動新的worker進程,採用新的設定檔

3. Nginx將新的請求指派新的worker進程

4. Nginx等待先前的worker進程的全部請求已經都返回後,關閉相關worker進程

5. 重複上面過程,知道全部舊的worker進程都被關閉掉

以上流程是參考nginx官方的相關文件後得出。

以 proxy_next_upstream為例, 一般的設定如下:

proxy_next_upstream http_504 timeout;

這個指令有兩個作用:

  1. 告訴nginx,如果發生了連線逾時,上游回傳504的時候,需要重試upstream
  2. 告訴nginx, http 504 ,連線逾時是 請求失敗

總的來說, nginx對於 error, timeout, invalide_header 都默認失敗, 其他的行為如果想當作失敗,需要加入類似 proxy_next_upstream之類的指令裡面的。 其中 http_403, http_404均不認識是失敗。

    論兩點, 對 server 失敗的定義 和 server失敗後的行為。
  • server 失敗的定義 : 上面的模組失敗定義主要用來說明一個請求在什麼情況下是失敗的;但是什麼定義一個server是失敗的呢? nginx裡面主要用兩個參數控制 : max_fails和fail_timeout。 簡單的說,如果一個請求在 fail_timeout內發生了max_fails次失敗,就認識改server目前是down。
  • 失敗後的行為: 主要為:
  • 在 fail_timeout 時間段,都不會選擇該server ;
  • 在 fail_timeout 時間後,會將該server標記為normal,重複現有的邏輯。

Ngxin把客戶端請求的處理過程分割成11個階段

#1  NGX_HTTP_POST_READ_PHASE:     讀取請求內容階段

##2  NGX_WRTP_SER : Server請求位址重寫階段

#3  NGX_HTTP_FIND_CONFIG_PHASE:    設定尋找階段

#4  NGX_HTTP_REWRITE_PHASE:    地址重寫提交階段

#6  NGX_HTTP_PREACCESS_PHASE:      存取權檢查準備階段

#7  NGX_HTTP_ACCESS_PHASE:    檢查提交階段

#9  NGX_HTTP_TRY_FILES_PHASE:      設定項目try_files處理階段

#10 NGX_HTTP_CONTENT_PHASE:        日誌模組處理階段

Nginx的請求處理流程

#1 Nginx如何確認由哪個server處理該請求?

1. 利用ip + port 確認監聽該ip和連接埠的server。

2. 根據請求中的host首部確認選擇那個server處理該請求。

3. 如果沒有符合任何server,則把該請求轉給預設(default)server處理,

   一般而言,不加任何設定的話,設定檔中順序出現的第一個server當

   default server。

4. 可以對listen指令使用default_server標誌,去設定某個server為

   default server。

#2 Nginx如何根據host首部來匹配server?

    Nginx主要是透過比較server中的server_name和host首部來匹配server的。

    比較順序如下圖所示:

1. 精確的name;

2. 最長配對的前導通配符name(如:*.zhidao.baidu.com) ;

3. 最長的後導通配符name(如:zhidao.baidu.*);

#3 初始化http請求,http請求的11個階段

location匹配指令

~      波浪線表示執行一個正規匹配,區分大小寫。

~*    表示執行一個正規匹配,不區分大小寫。

^~    ^~表示普通字元匹配,如果該選項匹配,只匹配該選項,不匹配別的選項,一般用來匹配目錄。

=      進行普通字元精確比對。

@     "@" 定義一個命名的 location,使用在內部導向時,例如 error_page,try_files。

範例: 


#請求URI範例:

  • / -> 符合configuration A

  • /documents/document.html -> 符合configuration B

  • /images/1.gif -> ; 符合configuration C  

  • /documents/1.jpg ->符合configuration D

##相關推薦:

nginx反向代理機制解決前端跨域問題

nginx如何修改上傳檔案大小

Nginx動靜分離操作講解#

以上是nginx相關知識點總結分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!