Nginx 的請求處理流程,你了解嗎?

  • 2019 年 11 月 10 日
  • 筆記

之前我們已經講解了 Nginx 的基礎內容,接下來我們開始介紹 Nginx 的架構基礎。

為什麼我們要討論 Nginx 的架構基礎?

因為 Nginx 運行在企業內網的最外層也就是邊緣節點,那麼他處理的的流量是其他應用服務器處理流量的數倍,甚至幾個數量級,我們知道任何一種問題在不同的數量級下,他的解決方案是完全不同的,所以在 Nginx 它所處理的應用場景中,所有的問題都會被放大,所以我們必須要去理解,為什麼 Nginx 採用 master-worker 這樣的一種架構模型,為什麼 worker 進程的數量要和 CPU 的核數相匹配?當我們需要在多個 worker 進程之間共享數據的時候,為什麼在 TLS 或者說限流、限速這樣的場景,他們的共享方式是有所不同的,那麼這些都需要我們對 Nginx 的架構有一個清晰的了解。

下面我們先來看一下 Nginx 的請求處理流程。

為什麼要去看 Nginx 中的請求處理流程呢?因為其實在之前中我們了解到 Nginx 會記錄 access 日誌和 error 日誌,也可以處理靜態的資源,那麼也可以做反向代理,那麼這些東西我們從 Nginx 內部去看他究竟是怎樣處理這些請求,它包含一些什麼樣的組成部分呢?

Nginx 的請求處理流程

Nginx的請求處理流程

我們從這張圖的最左邊來看,最左邊在 WEB、EMAIL 和 TCP,也就是說大致有三種流量從這裡進入 Nginx 以後,我們 Nginx 中有三個大的狀態機,一個是處理 TCP/UDP 的 4 層的傳輸層狀態機和處理應用層的 HTTP 狀態以及處理郵件的 MAIL 狀態機。

那麼為什麼我們叫它狀態機呢?是因為 Nginx 核心的這個大綠色的框他是用非阻塞的事件驅動處理引擎就是用我們所熟知的 epoll,那麼一旦我們使用這種異步處理引擎以後,通常都是需要用狀態機來把這個請求正確的識別和處理。

基於這樣的一種事件狀態處理機,我們在解析出請求需要訪問靜態資源的時候,我們看到走左下方的這個箭頭,那麼它就找到了靜態資源,如果我們去做反向代理的時候呢,那麼對反向代理的內容,我可以做磁盤緩存,緩存到磁盤上,也在下面左下方這條線,但是我們在處理靜態資源的時候,會有一個問題就是當整個內存已經不足以完全的緩存所有的文件和信息的時候,那麼像 send File 這樣的調用或者 AIO 會退化成阻塞的磁盤調用,所以在這裡我們需要有一個線程池來處理,對於每一個處理完成的請求呢,我們會進入 access 日誌或 error 日誌。

那麼這裡也是進入了磁盤中的,當然我們可以通過 syslog 協議把它進入到遠程的機器上,那麼更多的時候我們的 Nginx 是作為負載均衡或者反向代理來使用的,就是我們可以把請求通過協議級(HTTP,Mail 及 stream(TCP))傳輸到後面的服務器,也可以通過例如應用層的一些協議(FastCGI、uWSGI、SCGI、memcached)代理到相應的應用服務器。以上就是 Nginx 的請求處理流程。