OpenResty Edge 在閘道器(Edge Node)上快取 HTTP 響應,命中快取的請求無需再回源到後端,從而降低源站壓力和響應延遲。你只需在頁面規則裡開啟代理快取開關、設定快取鍵,再發布到每臺閘道器節點即可,全程無需改動 Nginx 配置、也無需 reload。本文演示完整步驟,並用 curl 逐一驗證 Cache-Status: HITMISS,最後展示如何在源站不返回 Cache-Control 頭時也強制快取。

快取未命中時,Edge 節點將請求轉發到後端伺服器

當客戶端請求命中 Edge Node 伺服器上的快取時,不需要向後端伺服器傳送請求。這樣可以減少響應延遲,節省網路頻寬——這也正是用 OpenResty Edge 構建私有 CDN 的核心機制。

快取命中時,Edge 節點直接返回響應,不再回源

在頁面規則中啟用代理快取並設定快取鍵

讓我們進入 OpenResty Edge 的 Admin Web 控制檯。這是我們控制檯的樣本部署。每個使用者都有自己的本地部署。

我們可以繼續之前的應用例子,test-edge.com

OpenResty Edge Admin Web 控制檯首頁

我們已經定義了一個上游。

已定義一個後端上游的上游列表

這個 my_backend 上游只有 1 個後臺伺服器。

只配置了一臺後端伺服器的 my_backend 上游

注意後臺伺服器的 IP 地址以 191 結尾。我們之後會用到這個 IP 地址。

以 191 結尾的後端伺服器 IP 地址

而且我們也已經定義了一個頁面規則。

已定義一條頁面規則的頁面規則列表

這個頁面規則設定了一個反向代理指向這個上游。

該頁面規則配置為指向上游的反向代理

顯然,我們還沒有為這個頁面規則啟用代理快取。

現在讓我們編輯這個頁面規則,在閘道器中新增響應快取。

編輯頁面規則以新增代理快取

讓我們啟用代理快取。

在頁面規則中開啟代理快取開關

這裡我們可以配置快取鍵。

為代理快取配置快取鍵

預設情況下,快取鍵由兩部分組成:URI,和查詢字串(URI 引數)。

你也可以選擇使用其他種類的鍵的組分。

選擇其他快取鍵組分

可選的快取鍵組分型別列表

或者我們可以將整個查詢字串從鍵中刪除。

將查詢字串從快取鍵中刪除

我們還可以新增更多的鍵組分。

向快取鍵中新增更多組分

在這個例子中,我們將只保留預設的快取鍵定義。

儲存此頁面規則。

儲存已啟用代理快取的頁面規則

讓我們釋出新的配置。

為待發布變更建立新版本

把我們剛才的變更推送出去。

推送前檢視待發布的變更

釋出!

確認釋出以推送變更

我們的新版配置現在已經同步到我們所有的閘道器伺服器了。

新版配置已同步到所有閘道器伺服器

我們的配置更改不需要重新載入伺服器、重新啟動或二進位制升級伺服器程序。所以它的效率非常高。

配置變更無需 reload 即可下發到閘道器節點

用 curl 測試快取並驗證 Cache-Status HIT/MISS

我們來測試一下閘道器伺服器的快取。

OpenResty Edge 控制檯中的閘道器伺服器列表

我們複製一下這個舊金山閘道器伺服器的 IP 地址。

複製舊金山閘道器伺服器的 IP 地址

注意這個 IP 地址的最後的數字是 133 。

在終端上,我們透過 curl 命令列工具向這個閘道器伺服器傳送 HTTP 請求。

curl -I -H 'Host: test-edge.com' http://138.68.231.133/

注意返回的 Cache-Status: MISS 響應頭。

curl 響應中返回的 Cache-Status: MISS 頭

再試一次。

curl -I -H 'Host: test-edge.com' http://138.68.231.133/

我們仍然收到 Cache-Status: MISS 頭。這意味著快取根本沒有被使用。這是為甚麼呢? 原來後端伺服器的原始響應頭裡缺少 ExpiresCache-Control 這樣的頭。

第二次請求仍然返回 Cache-Status: MISS

我們可以登入到後臺伺服器。

ssh ec2-user@54.213.103.191

記得後臺伺服器的 IP 地址是以 191 結尾的。

登入到 IP 以 191 結尾的後端伺服器

這個後臺伺服器執行的是開源的 OpenResty 軟體。

ps aux | grep nginx

後端執行著開源 OpenResty 的 nginx 程序

後臺伺服器可以執行任何其他的使用 HTTP 協議的軟體。

任何支援 HTTP 協議的軟體都可作為 Edge 後端

我們可以直接向這個後臺伺服器傳送測試請求。

curl -I -H 'Host: test-edge.com' http://127.0.0.1/

請注意,我們正在訪問本地主機。

透過 curl 直接向本地後端傳送請求

好吧,它確實沒有提供任何 ExpiresCache-Control 的響應頭。

後端響應中沒有 Expires 或 Cache-Control 頭

現在讓我們重新配置我們的後臺伺服器。

cd /usr/local/openresty/nginx/

開啟 nginx 配置檔案。

sudo vim conf/nginx.conf

找到我們的根,location /

在 nginx 配置檔案中找到根 location 塊

並增加 1 小時的過期時間。

expires 1h;

需要注意的是,後臺伺服器可以針對不同的 location 定義不同的過期時間。或者對某些響應完全禁用快取。

在後端 location 塊中新增 expires 1h 指令

儲存並退出檔案。

測試 nginx 配置檔案是否正確。

sudo ./sbin/nginx -t

沒有問題。

用 nginx -t 測試 nginx 配置檔案

現在重新載入後端伺服器程序。

sudo kill -HUP `cat logs/nginx.pid`

用 HUP 訊號 reload 後端 nginx 伺服器

注意,對於開源的 Nginx 伺服器,配置方法也是一樣的。

現在可以測試後臺伺服器了。

curl -I -H 'Host: test-edge.com' http://127.0.0.1/

好了,現在它響應頭裡有 ExpiresCache-Control 這兩個了。

後端現在返回 Expires 和 Cache-Control 頭

現在將請求傳送給閘道器伺服器。

curl -I -H 'Host: test-edge.com' http://138.68.231.133/

它仍然顯示的是 Cache-Status: MISS 頭。

向閘道器傳送的首個請求返回 Cache-Status: MISS

這是一次預期中的快取不命中。因為這是我們發的第一個請求。

首個請求未命中快取、回源到後端的示意圖

再次傳送請求。

curl -I -H 'Host: test-edge.com' http://138.68.231.133/

太好了!我們終於看到了 Cache-Status: HIT 頭!

向閘道器傳送的第二個請求返回 Cache-Status: HIT

終於如願以償地命中了快取。

第二個請求命中快取、不再回源的示意圖

如果我們新增一個查詢字串。

curl -I -H 'Host: test-edge.com' 'http://138.68.231.133/?a=3'

注意 a=3 的部分。

帶 a=3 查詢字串的請求返回快取未命中

那麼又會再次出現快取不命中。

這是因為預設的快取鍵包括查詢字串。

查詢字串是預設快取鍵的一部分,導致未命中

再次執行相同的請求應該就能命中快取了。

curl -I -H 'Host: test-edge.com' 'http://138.68.231.133/?a=3'

確實是被快取命中了。如果你不關心這個查詢字串,你可以把它從快取鍵中刪除。

重複傳送帶查詢字串的請求返回快取命中

源站無 Cache-Control 頭時強制快取

有時候我們就是懶得去改變後臺伺服器的配置。 那麼我們也可以在源站響應沒有出現任何快取控制頭的情況下,預設就對響應進行強制快取。

我們可以修改我們原來的頁面規則來實現這個功能。

開啟預設強制快取。

在頁面規則中開啟預設強制快取

還可以設定可快取響應狀態碼的預設過期時間。

設定可快取響應狀態碼的預設過期時間

我們將在另一個影片中演示這個功能。響應快取下來之後,當源站內容變化時,你還可以實時清除 HTTP 快取

常見問題

啟用代理快取後,為甚麼 OpenResty Edge 仍然返回 Cache-Status: MISS?

啟用代理快取後仍然是 Cache-Status: MISS,通常說明源站響應本身不可快取。本例中後端沒有返回 ExpiresCache-Control 頭,所以閘道器不會快取它。在後端 location 里加上 expires 1h;,源站就會帶上這些響應頭,此後第二次請求便會返回 Cache-Status: HIT

後端不返回 Cache-Control 頭時,如何快取響應?

編輯頁面規則、開啟預設強制快取,閘道器就會在源站不返回快取控制頭時也快取響應,你再為可快取的響應狀態碼設定預設過期時間即可。這樣無需改動後端伺服器的任何配置,就能在邊緣完成快取。

為甚麼加上查詢字串會導致快取未命中?

預設快取鍵由 URI 加查詢字串組成,因此帶 ?a=3 的請求與不帶它的請求是兩個不同的鍵,首次訪問會未命中快取;再次傳送同樣的請求就會命中。如果查詢字串不影響響應內容,可以把它從快取鍵中刪除,讓所有變體共用同一份快取。

修改 OpenResty Edge 快取配置需要 reload 或重啟 Nginx 嗎?

不需要。啟用代理快取併發布變更後,配置會同步到每一臺閘道器伺服器,無需 reload、重啟或二進位制升級伺服器程序,新的快取行為即時生效、不中斷服務。

關於 OpenResty Edge

OpenResty Edge 是一款專為微服務和分散式流量架構設計的全能型閘道器軟體,由我們自主研發。它集流量管理、私有 CDN 構建、API 閘道器、安全防護等功能於一體,幫助您輕鬆構建、管理和保護現代應用程式。OpenResty Edge 擁有業界領先的效能和可擴充套件性,能夠滿足高併發、高負載場景下的苛刻需求。它支援排程 K8s 等容器應用流量,並可管理海量域名,輕鬆滿足大型網站和複雜應用的需求。

如果你喜歡這個教程,請訂閱這個部落格網站和我們的 YouTube 頻道B 站頻道。謝謝!

關於作者

章亦春是開源 OpenResty® 專案創始人兼 OpenResty Inc. 公司 CEO 和創始人。

章亦春(Github ID: agentzh),生於中國江蘇,現定居美國灣區。他是中國早期開源技術和文化的倡導者和領軍人物,曾供職於多家國際知名的高科技企業,如 Cloudflare、雅虎、阿里巴巴, 是 “邊緣計算“、”動態追蹤 “和 “機器程式設計 “的先驅,擁有超過 22 年的程式設計及 16 年的開源經驗。作為擁有超過 4000 萬全球域名使用者的開源專案的領導者。他基於其 OpenResty® 開源專案打造的高科技企業 OpenResty Inc. 位於美國矽谷中心。其主打的兩個產品 OpenResty XRay(利用動態追蹤技術的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最適合微服務和分散式流量的全能型閘道器軟體),廣受全球眾多上市及大型企業青睞。在 OpenResty 以外,章亦春為多個開源專案貢獻了累計超過百萬行程式碼,其中包括,Linux 核心、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,並編寫過 60 多個開源軟體庫。

關注我們

如果您喜歡本文,歡迎關注我們 OpenResty Inc. 公司的部落格網站 。也歡迎掃碼關注我們的微信公眾號:

我們的微信公眾號

翻譯

我們提供了英文版原文和中譯版(本文) 。我們也歡迎讀者提供其他語言的翻譯版本,只要是全文翻譯不帶省略,我們都將會考慮採用,非常感謝!