使用 NGINX 進行微程序緩存的好處

【編者按】本文作者為 Owen Garrett,主要介紹使用 nginx 進行微程序緩存的好處,輔之以生動的實例。文章系國內 ITOM 管理平臺 OneAPM 編譯呈現。

NGINXNGINX Plus 被廣泛應用于網站內容緩存,小到個人網站,大到一些世界大型內容分發(fā)網站(CDNs),例如 MaxCDN 和 CloudFlare。

微程序緩存通過將動態(tài)、非個人化的內容緩存很短的時間,能有效加速這些內容的傳遞。在本文中,筆者將展示如何利用微程序緩存技術將一個基于 WordPress 的應用程序最高提速400倍。

為什么要緩存內容?

緩存能夠一舉兩得:通過更快地傳遞內容,緩存可以改善網站性能,同時減輕源服務器的負擔。緩存的效率取決于內容的緩存度。這些內容可以存儲多長時間,如何檢查更新,相同的緩存內容可以發(fā)給多少用戶?

使用 NGINX 進行微程序緩存的好處

緩存靜態(tài)內容,例如圖片、JavaScript 和 CSS 文件和幾乎不變的網頁內容是個相當簡單的過程。緩存更新的處理方法包括常規(guī)暫停、條件 Get,如果有必要,還可以用cache-busting技術來替換引用對象的URL。

緩存個人化內容(即通過服務器應用為每位用戶定制的內容)幾乎不可能,因為服務器對同一資源的每次請求的回復都不相同。服務器端引用(SSI)和頁面片段緩存(ESI)等技術可以協(xié)助組合網頁,但是這些技術很難實行,而且不一定能改善性能。

兩者中間是個有趣的待緩存對象:可能會無計劃更換,但是并非針對每位用戶(或者在客戶端通過 JavaScript實現個性化)的動態(tài)內容。這類內容的生成代價很高,提供過時版本又會帶來新的問題。

適合緩存的動態(tài)內容包括:

  • 經常更新的新聞或博客網站的首頁,每隔幾秒就有新文章發(fā)布
  • 最近資訊 RSS
  • 持續(xù)整合(CI)或搭建平臺的進度頁面
  • 庫存、進度或籌款計數
  • 彩票開獎結果
  • 日歷數據
  • 在客戶端呈現的個人化動態(tài)內容,例如利用 cookie 數據展示的廣告內容或數據(“你好,你的名字”)

動態(tài)內容的微程序緩存

微程序緩存是一種緩存技術,將內容緩存1秒左右很短的時間。這意味著網站更新會延遲不到1秒鐘,這在很多情況下是可以接受的。

這種短暫緩存能給網站性能帶來可察覺的改觀嗎?來試試看!

測試應用程序

在本次測試中,筆者用的是標準 WordPress 設置,并填充了一些樣本內容。

使用 NGINX 進行微程序緩存的好處
使用 NGINX 進行微程序緩存的好處

顯然,即便是處理基本內容,WordPress 服務器也存在性能問題:以 ab 為基準時,它一秒鐘只能服務5.53個請求:

root@nginx-client:~## ab -c 10 -t 30 -k http://nginx-server/
Requests per second:    5.53 [#/sec] (mean)
Time per request:       1809.260 [ms] (mean)
Time per request:       180.926 [ms] (mean, across all concurrent requests)
Transfer rate:          319.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:  1430 1735 259.4   1580    2228
Waiting:      537  683 119.7    624     980
Total:       1430 1735 259.4   1580    2228

測試中,vmstat 顯示造成瓶頸的原因是利用 PHP 生成頁面的 CPU 消耗(在 cpu 范圍的 us 一列,數值為96到98。)

root@nginx-server:/var/www/html## vmstat 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
10  0      0 136076  44944 585920    0    0     0     0  476 1665 96  4  0  0  0
10  0      0 140112  44952 585924    0    0     0     4  506 1773 98  2  0  0  0
10  0      0 136208  44952 585924    0    0     0     0  576 2057 97  3  0  0  0

熱門使用量顯示,CPU 被10個執(zhí)行 PHP 解釋器的 Apache httpd 進程占用。

這種設置本身就是問題——它限制了網站每秒鐘處理請求的數量不能超過5個,很容易遭到 DOS攻擊,而通過添加 CPU 來解決這個問題意味著每年的托管費用都要增加1000美元。

利用 NGINX 簡化微程序緩存

利用 NGINX 來加速服務只需兩步。

第一步: 通過 NGINX 代理服務器

在 WordPress 服務器安裝 NGINX 或 NGINX Plus 并進行配置,讓它接收訪問流量并在內部轉發(fā)到 WordPress 服務器:

使用 NGINX 進行微程序緩存的好處
使用 NGINX 進行微程序緩存的好處

NGINX 代理服務器配置比較簡單:

server {
    listen external-ip:80;  # External IP address

    location / {
        proxy_http_version 1.1; # Always upgrade to HTTP/1.1
        proxy_set_header Connection ""; # Enable keepalives
        proxy_set_header Accept-Encoding ""; # Optimize encoding
        proxy_pass http://wordpress-upstreams;
    }

    status_zone wordpress; # NGINX Plus status monitoring
}

upstream wordpress-upstreams {
    zone wordpress 128k;
    keepalive 20; # Keepalive pool to upstream

    server localhost:80;
}

筆者還修改了 Apache 配置(監(jiān)聽端口號和虛擬服務器),這樣 Apache 就綁定到了 localhost:80。

你可能以為添加額外的代理服務器會對性能造成負面影響,但是實際上性能變化可以忽略不計:

root@nginx-client:~# ab -c 10 -t 30 -k http://nginx-server/
Requests per second:    5.63 [#/sec] (mean)
Time per request:       1774.708 [ms] (mean)
Time per request:       177.471 [ms] (mean, across all concurrent requests)
Transfer rate:          324.44 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       1
Processing:  1423 1709 341.3   1532    2794
Waiting:      554  703 165.0    608    1165
Total:       1423 1709 341.4   1532    2794

在更繁忙的服務器(處理更多并發(fā)請求)中,僅靠 NGINX 實現的優(yōu)化就能帶來顯著的性能提升

第二步: 啟動短期緩存

在服務器配置中只添加了兩條指令,NGINX 或 NGINX Plus 就可以緩存所有可緩存的響應。帶有 200 OK 狀態(tài)碼的響應只緩存1秒鐘。

proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;

server {
    proxy_cache cache;
    proxy_cache_valid 200 1s;
    ...
}

筆者再次運行基準測試時,看到了性能顯著提升:

root@nginx-client:~# ab -c 10 -t 30 -k http://nginx-server/
Complete requests:      18022
Requests per second:    600.73 [#/sec] (mean)
Time per request:       16.646 [ms] (mean)
Time per request:       1.665 [ms] (mean, across all concurrent requests)
Transfer rate:          33374.96 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.5      1      10
Processing:     0   16 141.5      3    2119
Waiting:        0    6  54.6      1     818
Total:          1   17 141.5      4    2121

這是120倍的性能優(yōu)化,從每秒鐘處理5條請求到600條;這聽起來太棒了,不過還有個問題。

緩存進展順利,筆者驗證了內容的確是每秒更新的(因此永不過時),但是未曾預料到的情況發(fā)生了。你會發(fā)現處理時間的標準偏差很大(141.5毫秒)。CPU 使用率還是100%(用 vmstat 測量),熱門使用量顯示有10個活躍的 httpd 進程。

筆者還從 NGINX Plus 的活動檢測控制面板找到進一步的線索。測試前:

使用 NGINX 進行微程序緩存的好處
使用 NGINX 進行微程序緩存的好處

測試后:

使用 NGINX 進行微程序緩存的好處
使用 NGINX 進行微程序緩存的好處

控制面板報告顯示,NGINX 在測試期間處理了18032條請求(ab 匯報的18022條請求,以及基準在30秒結束時突出的10條請求)。但是,NGINX 轉發(fā)了150條請求到上游服務器,在緩存內容1秒鐘的情況下,這比我們期望的30秒測試應有的請求數多得多。

怎么回事?為什么 CPU 使用率很高,緩存更新比預期數字更大?

這是因為每次緩存條目過期時,NGINX 就會停止使用它。NGINX 將所有請求都轉發(fā)給上游 WordPress 服務器,直到它收到響應,可以用新內容來緩存。

這導致了 WordPress 服務器收到的請求經常激增到10條。這些請求會占用 CPU,比緩存響應的請求延遲更多,這就解釋了測試結果中的高標準差。

用 NGINX 優(yōu)化微程序緩存

筆者想要的策略很清晰:需要在確保緩存內容最新的情況下,盡可能少地向上游源服務器轉發(fā)請求。在緩存內容不斷更新的前提下,筆者愿意從緩存獲取舊的(延后1到2秒)響應。要實現這一目標,需要添加兩條指令:

  • proxy_cache_lock ——限制填充緩存的并發(fā)嘗試數量,這樣當一條緩存入口被創(chuàng)建后,對該資源的請求將會在 NGINX 中排隊。
  • proxy_cache_use_stale ——配置 NGINX,使它提供舊的(最近緩存的)內容,同時更新緩存入口。

加上之前已經添加的緩存指令,筆者得到如下服務器配置:

server {
    proxy_cache one;
    proxy_cache_lock on;
    proxy_cache_valid 200 1s;
    proxy_cache_use_stale updating;
    ...
}

基準測試結果的變化十分驚人。每秒鐘的請求數量從600跳躍到接近2200:

root@nginx-client:~# ab -c 10 -t 30 -n 100000 -k http://nginx-server/
Concurrency Level:      10
Time taken for tests:   30.001 seconds
Complete requests:      65553
Failed requests:        0
Keep-Alive requests:    0
Total transferred:      3728905623 bytes
HTML transferred:       3712974057 bytes
Requests per second:    2185.03 [#/sec] (mean)
Time per request:       4.577 [ms] (mean)
Time per request:       0.458 [ms] (mean, across all concurrent requests)
Transfer rate:          121379.72 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.3      1       5
Processing:     1    4   8.1      3     661
Waiting:        0    1   2.6      1     250
Total:          1    5   8.1      4     661

CPU 使用率也低多了(注意 cpu 下面 id 一欄的空閑時間):

root@nginx-server:/var/www/html# vmstat 3
procs -----------memory---------- ---swap-- -----io---- -system--- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs  us sy id wa st
 1  0      0 106512  53192 641116    0    0     0    37 11016 3727 19 45 36  0  0
 1  0      0 105832  53192 641808    0    0     0    68 17116 3521 13 56 31  0  0
 1  0      0 104624  53192 643132    0    0     0    64 14120 4487 15 51 33  0  0

數據傳輸率(121379.72千字節(jié)/秒,或121兆字節(jié)每秒)相當于0.97千兆,因此該測試受網絡限制。CPU 平均使用率為66%,該服務器的峰值性能應該大概為2185/0.66 = 3300 個請求/秒。

使用 NGINX 進行微程序緩存的好處
使用 NGINX 進行微程序緩存的好處

另外,關注 ab 報告的連續(xù)響應時間(標準偏差只有8.1毫秒),以及操作面板顯示的30秒測試中轉發(fā)給上游服務器的請求數量很少(16):

使用 NGINX 進行微程序緩存的好處
使用 NGINX 進行微程序緩存的好處

為什么只有16條請求?我們知道緩存到1秒鐘時會清零,這個更新過程最多需要0.661秒(從 ab 結果來看),因此可以推測,更新頻率不會快于每1.66秒一次。在30秒鐘的時間之外,只會收到最多18(30/1.66)條請求。

了解更多

本文簡單展示了在短時間內緩存動態(tài)內容可能帶來的好處,以及 NGINX Plus 的活動監(jiān)測數據在調整和診斷緩存配置時的用處。如果你想在生產環(huán)境中使用微程序緩存,筆者建議你創(chuàng)建并測試一個更為復雜的緩存規(guī)則,針對更長時間內的微程序緩存動態(tài)和靜態(tài)內容。

NGINX Plus 還有一項緩存清除功能,可以用來迅速清除 NGINX 緩存中的特定內容。如果你想緩存更長時間的內容,可以將該功能編入程序,但是一旦你更改原始內容,就要立即更新該程序。

要想了解更多信息,請查閱以下資源:

本文系 OneAPM 工程師編譯呈現。OneAPM Browser Insight 是一個基于真實用戶的 Web 前端性能監(jiān)控平臺,能夠幫大家定位網站性能瓶頸,網站加速效果可視化;支持瀏覽器、微信、App 瀏覽 HTML 和 HTML5 頁面。想閱讀更多技術文章,請訪問 OneAPM 官方技術博客。

本文轉自 OneAPM 官方博客

原文地址: https://www.nginx.com/blog/benefits-of-microcaching-nginx/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 本文轉載自:眾成翻譯譯者:為之漫筆鏈接:http://www.zcfy.cc/article/22原文:https...
    極樂君閱讀 773評論 0 10
  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx?那么一定聽過它的“同行”Apache吧!Ngi...
    JokerW閱讀 33,042評論 24 1,002
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 136,724評論 19 139
  • 1.簡介: ? Nginx:engine X ,2002年,開源,商業(yè)版? http協(xié)議:web服務器(類似于ht...
    尛尛大尹閱讀 2,021評論 0 3
  • 為什么我們的時間不夠用,因為我們的貪婪把所有的時間全部殺死!因為我們的欲望把所有的計劃統(tǒng)統(tǒng)消滅! 一看標題就知道這...
    花園里的皮皮閱讀 404評論 0 0

友情鏈接更多精彩內容