Nginx 的過濾模塊是幹啥用的?

来源:https://www.cnblogs.com/iziyang/archive/2020/05/27/12970270.html
-Advertisement-
Play Games

上一篇文章我寫了 Nginx 的 11 個階段,很多人都說太長了。這是出於文章完整性的考慮的,11 個階段嘛,一次性說完就完事了。今天這篇文章比較短,看完沒問題。 過濾模塊的位置 之前我們介紹了 Nginx 的 11 個階段,在 content 階段時,Nginx 會生成返回給用戶的響應內容,對用戶 ...


上一篇文章我寫了 Nginx 的 11 個階段,很多人都說太長了。這是出於文章完整性的考慮的,11 個階段嘛,一次性說完就完事了。今天這篇文章比較短,看完沒問題。

過濾模塊的位置

之前我們介紹了 Nginx 的 11 個階段,在 content 階段時,Nginx 會生成返回給用戶的響應內容,對用戶的響應內容,實際上還需要做再加工處理,Nginx 的過濾模塊就是對響應內容進行再加工處理的。所以實際上過濾模塊位於 content 階段之後,log 階段之前。

我們先來看一段配置指令:

limit_req zone=req_one
burst=120;
limit_conn c_zone 1;

satisfy any;
allow 192.168.1.0/32;
auth_basic_user_file access.pass;

gzip on;
image_filter resize 80 80;

那麼在這一段配置指令之下,會遵循怎樣的請求流程呢?請看一下下麵這張圖:

上面這張圖的流程大致說一下,如果對於 Nginx 的 11 個階段不瞭解的去翻一下之前的文章。

我這裡再簡單說一下。首先由 Nginx 框架接收 HTTP 請求,經過 preaccess、access、content 階段的處理,當經過 static 模塊之後生成響應的時候,很多時候需要對響應進行處理,然後才會返回給客戶端。

這裡我們假如響應是一張圖片的話,那麼需要做縮略圖的時候,首先就要經過 image_filter 模塊的處理。這裡面還有一個 gzip 模塊,這兩個模塊也是需要遵循嚴格的順序的。因為如果先做 gzip 壓縮的話,縮略圖後面就沒辦法做了。

第二個需要關註的地方是,首先對 header 進行過濾,再對 body 進行過濾。因為我們在對用戶發送響應的時候,一定是先發送 header,然後再發送 body,所以所有的過濾模塊都會提供對 header 或 body 的過濾,當然 image_filter 和 gzip 模塊對這兩者都可以過濾。

返迴響應

前面我們說過,Nginx 的 11 個階段是有嚴格的順序的,而這個順序是在 Nginx 的代碼中以一個數組的形式存在的,這個數組的順序是從後往前。在給用戶返迴響應的時候,過濾模塊也是有嚴格順序的,這個順序同樣是從後往前。來看一下在代碼中的定義,標紅的是我下麵會提到的幾個過濾模塊。

我們需要重點關註四個過濾模塊,它們分別的作用是啥呢?

  • copy_filter:複製包體內容

    當我們使用 sendfile 指令的時候,也就是零拷貝技術,不經過用戶態記憶體,這裡就是不經過 Nginx 直接發給用戶,同時也用了 gzip 模塊的時候,gzip 是必須在 copy_filter 模塊之後的,因為 gzip 必須對記憶體中的數據做壓縮,這時 copy_filter 就會讓 sendfile 指令失效。有些模塊不需要對記憶體中的數據進行處理,就需要在 copy_filter 模塊之前進行處理。

  • postpone_filter:處理子請求

    用來處理子請求,有些過濾模塊需要關心子請求的處理結果,需要放在該模塊之後。

  • header_filter:構造響應頭部

    用來構造最終發送給用戶的響應頭部,可能會添加一些 Server,Nginx 版本號等內容。

  • write_filter:發送響應

    用來實際調用操作系統的 write 或 send 等系統調用,來把響應實際發送出去。

介紹完了過濾模塊的功能以及所處的階段,下麵來具體看兩個模塊。

sub 模塊

介紹一個可以替換響應中字元串內容的模塊:sub 模塊。

  • 功能:將響應中指定的字元串,替換成新的字元串
  • 模塊:ngx_http_sub_filter_module 模塊,預設未編譯進 Nginx,通過 --with-http_sub_module 啟用

指令

Syntax: sub_filter string replacement;
Default: —
Context: http, server, location

Syntax: sub_filter_last_modified on | off;
Default: sub_filter_last_modified off; 
Context: http, server, location

Syntax: sub_filter_once on | off;
Default: sub_filter_once on; 
Context: http, server, location

Syntax: sub_filter_types mime-type ...;
Default: sub_filter_types text/html; 
Context: http, server, location

來解釋一下這四個指令都是啥意思。

  • sub_filter string replacement

    sub_filter 指令會把匹配到的 string 字元串替換成 replacement 表示的字元串。

  • sub_filter_last_modified on | off

    sub_filter_last_modified 指令的意思是,是否要返回原來的 last_modified HTTP 頭部,因為我們已經修改了文件內容,如果是 on 的話,就會繼續返回原來的頭部。

  • sub_filter_once on | off

    sub_filter_once 的意思是,是否只替換一次,預設打開,如果設置為 off 的話,那就會將響應中的內容全部掃描一遍並替換。

  • sub_filter_types mime-type

    這個指令是說針對那些文件類型進行替換,這裡可以設置成 *,但是效率就會比較低了,需要根據實際情況考慮。

實戰

配置文件如下:

server {
	server_name sub.ziyang.com;
	error_log  logs/myerror.log  info;
	
	location / {
    	sub_filter 'Nginx.oRg'  '$host/nginx';
    	sub_filter 'nginX.cOm' '$host/nginx';
    	#sub_filter_once on;
		sub_filter_once off;
		#sub_filter_last_modified off;
		sub_filter_last_modified on;
	}	
}

這裡需要重新編譯 Nginx,我這裡把下一節需要的模塊也一起編譯進去了:

./configure --prefix=/Users/mtdp/myproject/nginx/test_nginx --with-http_sub_module --with-http_addition_module --with-http_realip_module
make
cp nginx ../../test_nginx/sbin/ # 複製編譯好的 nginx 到之前的目錄

執行熱部署:

熱部署的流程詳見 Nginx 入門及命令行操作

kill -USR2 87693 # 使用新的 Nginx 二進位文件提供服務
kill -WINCH 87693 # 退出老的 Nginx 的 worker 進程
kill -quit 87693 # 優雅的退出老的 master 進程

在瀏覽器中打開 sub.ziyang.com:

這裡面會發現,nginx.org 已經替換成了 sub.ziyang.com/nginx,nginx.com 也替換成了 sub.ziyang.com/nginx。

addition 模塊

下麵再來看一個過濾模塊,addition 模塊,它可以在響應的前後添加內容。

  • 功能:在相應前或者響應後增加內容,增加內容的方式,是通過新增子請求,根據子請求的響應來完成。

  • 模塊:ngx_http_addition_filter_module

    預設未編譯進 Nginx,通過 --with-http_addition_module 啟用

指令

Syntax: add_before_body uri;
Default: —
Context: http, server, location

Syntax: add_after_body uri;
Default: —
Context: http, server, location

Syntax: addition_types mime-type ...;
Default: addition_types text/html; 
Context: http, server, location

這裡的三個指令都比較簡單,說一下 add_before_bodyadd_after_body 後面的 uri,這個的意思是說,向指定 uri 發起子請求,根據子請求的響應來添加內容。

addition_types 指令是指定要添加的文件類型。

實戰

配置文件如下:

server {
	server_name addition.ziyang.com;
	error_log logs/myerror.log info;
	
	location / {
    	#add_before_body /before_action;
    	#add_after_body  /after_action;
		#addition_types *;
	}	
	location /before_action {
		return 200 'new content before\n';
	}
	location /after_action {
		return 200 'new content after\n';
	}
	location /testhost {
		uninitialized_variable_warn on;
		set $foo 'testhost';
		return 200 '$gzip_ratio\n';
	}
}

先看在註釋掉 addition 模塊的指令的情況下,會是什麼效果:

➜  ~ curl addition.ziyang.com/a.txt
a

然後打開註釋:

➜  ~ curl addition.ziyang.com/a.txt
new content before
a
new content after

在原響應前後都增加了內容。

這裡面需要註意一點,在實際情況下,add_before_bodyadd_after_body 後面是其他的 uri,我這裡為了簡化,直接轉發到對應的 location。

本文涉及到的所有配置文件我已經放在了 Nginx 配置文件,大家可以自取。


本文首發於我的個人博客:iziyang.github.io


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實驗內容: 找一個系統調用,系統調用號為學號最後 2位相同的系統調用【即 97號系統調用】 通過彙編指令觸發該系統調用 通過 gdb 跟蹤該系統調用的內核處理過程 重點閱讀分析系統調用入口的保存現場、恢復現場和系統調用返回,以及重點關註系統調用過程中內核堆棧狀態的變化 實驗環境: VMWare虛擬機 ...
  • Lighttpd 像 Ngnix 一樣,是被設計運行在低記憶體,低 CPU 負載的設備上,它們都非常適合在樹莓派上運行。 本文將介紹如何在樹莓派上運行基本配置的 Lighttpd ,以及如何與 PHP-FRM 一起使用。 安裝 Lighthttpd 首先,我們先保證我們的樹莓派軟體都是最新的: $ s ...
  • 問題來源 2020年5月3日星期天。晚上7點39分,正是結賬的高峰期,然而就是在這個時候系統崩潰了。牽扯到錢的事沒一件事小事,可以定性此為重大事故。 造成的後果: 有人必須要背鍋了,先恢復再找問題源頭,再找誰的問題(這種鍋絕大多數是開發的問題)。 問題處理 常見思路:回滾、重啟大法!!! 先恢復再查 ...
  • corosync v1 + pacemakerCorosync: OpenAIS發展到Wilson版本後衍生出來的開放性集群引擎工程,提供心跳消息檢測及成員管理。Pacemaker: 集群資源管理器。它利用集群基礎構件(OpenAIS 、heartbeat或corosync)提供的消息和成員管理能力... ...
  • Linux系統CentOS6.9 x64 配置jdk和MySQL8.0環境,授予MySQL遠程訪問許可權 ...
  • 問題:對磁碟進行分區,分區後使用mount命令進行掛接,提示mount: unknown filesystem type 'ext4'錯誤,無法完成掛接。問題分析:查看當前伺服器支持的文件系統,命令:cat /proc/filesystems圖1為產生上述錯誤的伺服器,圖2為可以正常掛接的伺服器,對... ...
  • () 批量ping for /L %i IN (起始,掃描間距,結束) DO ping -w 2 -n 1 10.224.131.%i 如 for /L %i IN (55,1,80) DO ping -w 2 -n 1 10.224.131.%i 輸出到指定文件 arp -a > 111.txt ...
  • 1. 基礎環境準備1.1 環境準備:兩台虛擬機 db01 db02每台創建四個mysql實例:3307 3308 3309 33101.2 刪除歷史環境:pkill mysqldrm -rf /data/33{07..10} mv /etc/my.cnf /etc/my.cnf.bak 1.3 創建 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...