日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Nginx >内容正文

Nginx

Nginx的执行阶段详解

發布時間:2025/3/8 Nginx 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Nginx的执行阶段详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在了解nginx的執行階段前,先看一個例子

對echo不熟悉的,可以先看文章Nginx調試必備了解下echo擴展

?

回到上面這個例子,在server塊中配置這樣的location,你覺得輸出是什么樣子?

?

按照正常的邏輯,輸出應該是32 56,我們請求下,看下nginx處理的結果

?

兩次輸出都是56,顛覆認知。這就是因為set和echo處在nginx不同的執行階段,在nginx中,處在不同階段的配置,和配置文件順序沒有任何關系

?

Nginx處理請求過程總共劃分為11個階段,按順序依次是post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、precontent、content以及log

?

看一下nginx源碼中的定義,在http/ngx_http_core_module.h中

我這里是1.17.7版本的nginx,我看了nginx1.16.0版本一樣,老一點的版本內容預處理階段是try_files階段

?

下面結合測試詳細說一下每個階段

?

post-read 階段

?

?

該階段是nginx接收完請求頭之后的第一個階段,它位于uri重寫之前,該階段很少用,很少有模塊會注冊在該階段,默認情況下,該階段被跳過,但是有個兩個標準函數是注冊在這個階段的,set_real_ip_from、real_ip_header

?

看到real_ip有沒有很熟悉,通常nginx日志或者后端需要獲取客戶端真實IP的時候,需要把cdn或者你前端的nginx或者代理的ip改寫之后來獲取,就會用到這個,下面看例子

?

?

通過curl -H添加header頭請求,然后查看結果

?

通常多級代理,后端要獲取真實IP就是通過這種自定義header的方式去獲取

?

?

server-rewrite 階段

?

?

該階段是server級別的uri重寫階段,該階段執行處于server塊內,location塊外的重寫指令,在讀取請求頭的過程中nginx會根據host及端口找到對應的虛擬主機配置

?

該階段不只是執行rewrite指令,通常該階段包含標準函數ngx_rewrite、set,看例子

?

?

這里在server塊內,location塊外set一個變量$a,在location中引用,因為server-rewrite階段在前面,所以$a變量會先賦值,查看結果

?

?

find-config 階段

?

?

該階段是尋找location配置階段,該階段使用重寫之后的uri來查找對應的location,如果匹配到的location中有重寫指令的話,該階段會再次執行,直到匹配到最終的location

?

這個階段的匹配工作是由nginx核心模塊來完成的,并不支持nginx模塊注冊處理程序

?

這個階段不太好整例子,想來想去沒有想到可以體現的例子,但是debug日志可以體現,用上一個階段的例子的請求日志看下

?

?

很直觀,在執行完上個階段的set $a之后,就開始匹配location,最終匹配到test,接著執行下面的階段

?

?

rewrite 階段

?

?

該階段是location級別的uri重寫階段,該階段執行location基本的重寫指令,同樣也可能被指定多次

?

直接寫個跳轉看日志

?

通過curl -L跟隨跳轉請求看下結果

?

查看debug日志

?

仍然是先執行server塊內的set,之后匹配到rewrite的location,然后執行location內的rewrite

?

?

post-rewrite階段

?

?

該階段是location級別重寫的后一個階段,用來檢查上階段是否有uri重寫,并根據結果跳轉到合適的階段

?

這個階段緊接上一個階段,是由nginx核心完成rewrite階段所要求的跳轉,即內部跳轉

?

內部跳轉本質上其實就是把當前的請求處理階段跳回到find-config階段,類似于條件分支循環,這也就是上面說到find-config階段會被多次執行的原因。把上階段的rewrite請求跳轉到find-config階段,重新進行請求uri和location配置塊的配對,這個過程可以從上面階段的后續debug日志可以看出來

?

rewrite被改寫到test,然后開始重新匹配uri為test的location

?

接著執行find-config階段的匹配過程,然后執行后面的階段

?

?

preaccess 階段

?

?

該階段是訪問權限控制的前一階段,預控制階段。該階段在權限控制階段之前,一般也用于訪問控制,比如limit的限制速率、限制連接數等

?

該階段包含的標準函數ngx_limit_req、ngx_limit_zone等

?

實例結合后面的下個階段一起看

?

?

access 階段

?

?

該階段是權限訪問控制階段,比如基于IP黑白名單的權限控制,基于用戶名密碼的權限控制等

?

該階段包含的標準函數ngx_access、ngx_auth_request函數等

?

結合preaccess,我們在同一個location中配置limit和access,如下

?

然后請求access看下結果

?

看下debug日志,分析處理階段

?

先處理limit,然后接著處理access部分

?

post-access 階段

?

?

該階段是訪問控制的后一階段,和post-rewrite階段類似,不支持nginx模塊注冊處理程序,由nginx核心自己完成處理工作,主要是配合access階段實現后續處理

?

這里常用的指令是satisfy,它的功能類似if判斷中的“與”、“或”關系,在access階段可以注冊多個nginx模塊,比如上面提到的access模塊和auth認證模塊,如果兩個模塊都注冊了,那么是執行哪個?按哪個匹配結果來執行,這個時候就用到satisfy,它就是讓多個控制之間彼此協作

?

比如上面兩個模塊都在access階段注冊了與訪問控制相關的處理程序,那就有兩種協作方式,一是模塊access和auth都通過驗證才算通過,另外一種是只要其中任一通過驗證就算通過。第一種方式為all方式,也就是“與”關系,第二種方式為any方式,也就是“或”關系,默認情況下nginx使用的是all方式

?

?

precontent 階段

?

?

該階段為生成內容的前一階段,主要是用于處理try_files指令的配置,如果沒有配置try_files指令,這個階段會跳過,該階段不支持nginx模塊注冊處理程序

?

try_files指令接受兩個以上任意數量的參數,每個參數都指定一個uri,比如設置N個參數,nginx會在precontent階段依次把前N-1個參數映射為文件系統上的文件或目錄,逐個檢查這些文件或目錄是否存在。一旦Nginx匹配到某個文件或目錄存在,就會在precontent階段,把當前請求的uri改寫為該對象所對應的參數uri,如果前N-1個參數所對應的文件或目錄都不存在,則precontent階段會發起內部跳轉,按照最后一個參數所指定的uri進行find-config階段

?

配置個try_files來看下執行過程

?

請求try,看下結果

并沒有執行echo uri部分,而是到test的location了,看下debug日志

?

可以看到和我們上面說的結果一致

?

?

content 階段

?

?

該階段是所有階段中最重要的一個階段,該階段負責內容生成,并輸出http響應。通過nginx配置文件中的配置指令,生成響應內容,返回給客戶端,這個階段的配置指令例如echo、proxy_pass等

?

日志體現該階段

?

?

?

log 階段

?

?

?該階段就是日志記錄階段,根據log配置寫入日志文件,比如log級別,日志格式logformat等,包含nginx的access_log和error_log等

?

在debug日志中也有記錄

請求返回給客戶端后,記錄日志,然后保持keepalive,如果是不需要keepalive的時候,直接close連接

?

以上就是nginx處理請求的11個階段,熟悉之后,對nginx的了解更深

總結

以上是生活随笔為你收集整理的Nginx的执行阶段详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。