簡單一招竟把nginx伺服器效能提升50倍
來源:京東雲開發者
本文記錄了一次基於實際業務場景的nginx調優過程,透過一步步的分析實踐把伺服器整體效能提升了50倍。
架構流程大致如下所示:
資料更新後會重新生成新一輪次的檔案,重新整理 CDN 的時候會觸發大量回源請求,應用伺服器極端情況得 hold 住這 9w 的 QPS。
雙機房一共 40 臺 4C 的機器,25KB 資料檔案,5w 的 QPS 直接把 CPU 打到 90%。
這明顯不符合業務需求啊,咋辦?先無腦加機器試試唄。
就在這時測試同學反饋壓測的資料不對,最後一輪檔案最大會有 125KB,雪上加霜。
於是乎檔案替換,機器數量整體翻一倍擴到 80 臺,服務端 CPU 依然是瓶頸,QPS 加不上去了。
到底是哪裡在消耗 CPU 資源呢,整體架構已經簡單到不能再簡單了。
這時候我們注意到為了節省網路頻寬 nginx 開啟了 gzip 壓縮,是不是這小子搞的鬼。
server
{
listen 80;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain application/css text/css application/xml text/javascript application/javascript application/x-javascript;
......
}
為了驗證這個猜想,我們把 nginx 中的 gzip 壓縮率從 6 調成 2,以減少 CPU 的計算量。
gzip_comp_level 2;
這輪壓下來 CPU 還是很快被打滿,但 QPS 勉強能達到 9w,坐實了確實是 gzip 在耗 CPU。
nginx 作為家喻戶曉的 web 伺服器,以高效能高併發著稱,區區一個靜態資料檔案就把應用伺服器壓的這麼高,一定是哪裡不對。
明確了 gzip 在耗 CPU 之後我們潛下心來查閱了相關資料,發現了一絲進展。
html/css/js 等靜態檔案通常包含大量空格、標籤等重複字元,重複出現的部分使用「距離加長度」表達可以減少字元數,進而大幅降低頻寬,這就是 gzip 無失真壓縮的基本原理。
作為一種端到端的壓縮技術,gzip 約定檔案在服務端壓縮完成,傳輸中保持不變,直到抵達客戶端。這不妥妥的理論依據嘛~
nginx 中的 gzip 壓縮分為動態壓縮和靜態壓縮兩種:
•動態壓縮
伺服器給客戶端返回響應時,消耗自身的資源進行實時壓縮,保證客戶端拿到 gzip 格式的檔案。
這個模組是預設編譯的,詳情可以檢視
•靜態壓縮
直接將預先壓縮過的 .gz 檔案返回給客戶端,不再實時壓縮檔案,如果找不到 .gz 檔案,會使用對應的原始檔案。
這個模組需要單獨編譯,詳情可以檢視
如果開啟了 gzip_static always,而且客戶端不支援 gzip,還可以在服務端加裝 gunzip 來幫助客戶端解壓,這裡我們就不需要了。
查了一下 jdos 自帶的 nginx 已經編譯了 ngx_http_gzip_static_module,省去了重新編譯的麻煩事。
接下來透過 GZIPOutputStream 在本地額外生成一個 .gz 的檔案,nginx 配置上靜態壓縮再來一次。
gzip_static on;
面對 9w 的QPS,40 臺機器只用了 7% 的 CPU 使用率完美扛下。
為了探底繼續加壓,應用伺服器 CPU 增長緩慢,直到網路流出速率被拉到了 89MB/s,擔心影響宿主機其他容器停止壓力,此時 QPS 已經來到 27w。
qps 5w->27w 提升 5 倍,CPU 90%->7% 降低 10 倍,整體效能翻了 50 倍不止,這回舒服了~
經過一連串的分析實踐,似乎靜態壓縮存在“壓倒性”優勢,那什麼場景適合動態壓縮,什麼場景適合靜態壓縮呢?一番探討後得出以下結論:
純靜態不會變化的檔案適合靜態壓縮,提前使用gzip壓縮好避免CPU和頻寬的浪費。動態壓縮適合API介面返回給前端資料這種動態的場景,資料會發生變化,這時候就需要nginx根據返回內容動態壓縮,以節省伺服器頻寬。
作為一名後端工程師,nginx 是我們的老相識了,抬頭不見低頭見。日常工作中配一配轉發規則,查一查 header 設定,基本都是把 nginx 作為反向代理使用。這次是直接訪問靜態資源,調整過程的一系列最佳化加深了我們對 gzip 的動態壓縮和靜態壓縮的基本認識,這在 NG 老炮兒眼裡顯得微不足道,但對於我們來說卻是一次難得的技能擴充機會。
在之前的職業生涯裡,我們一直聚焦於業務架構設計與開發,對效能的最佳化似乎已經形成思維慣性。面對大資料量長事務請求,減少迴圈變批次,增大併發,增加快取,實在不行走非同步任務解決,一般瓶頸都出現在 I/O 層面,畢竟磁碟慢嘛,減少與資料庫的互動次數往往就有效果,其他大機率不是問題。這回有點兒不一樣,CPU 被打起來的原因就是出現了大量資料計算,在高併發請求前,任何一個環節都可能產生效能問題。
- END -
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024923/viewspace-3006579/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- nginx與lighttpd效能簡單對比薦Nginxhttpd
- nginx靜態資源伺服器簡單配置Nginx伺服器
- 三種提升Java程式碼效能的簡單技巧 - levelupJava
- Nginx簡單操作Nginx
- nginx引數調優能提升多少效能Nginx
- MobileNet 結構簡單微調的一點效能提升
- Nginx引入執行緒池 效能提升9倍Nginx執行緒
- Nginx 引入執行緒池,提升 9 倍效能Nginx執行緒
- 怎麼去提升伺服器的效能?伺服器
- 企業怎麼提升伺服器效能伺服器
- 高效能Web伺服器Nginx的配置與部署研究(1)Nginx簡介及入門示例Web伺服器Nginx
- 最簡單的docker教程:在docker裡執行nginx伺服器DockerNginx伺服器
- 企業怎麼提升伺服器的效能伺服器
- nginx部署及簡單優化Nginx優化
- Nginx 簡單應用(Windows os)NginxWindows
- 簡單一招實現json資料視覺化JSON視覺化
- 如何提升高併發量伺服器的效能伺服器
- mysql簡單效能測試MySql
- nginx: 高效能http和反向代理伺服器NginxHTTP伺服器
- 簡單介紹nginx 變數使用Nginx變數
- Nginx 快取使用指南-簡單Nginx快取
- Nginx 簡單入門指北不指南Nginx
- Nginx反向代理的簡單實現Nginx
- 提升網站效能:Nginx五種高效負載均衡策略詳解!網站Nginx負載
- javascript變數宣告提升簡單介紹JavaScript變數
- Windows IO 效能簡單測試Windows
- Jmeter效能測試簡單使用JMeter
- try的簡單效能測試
- 簡單實踐搭建 nginx 負載均衡Nginx負載
- CenterOS docker 下簡單部署 PHP+NginxROSDockerPHPNginx
- 簡單介紹nginx反向代理及使用Nginx
- Nginx實現簡單的負載均衡Nginx負載
- Nginx簡單的負載均衡配置示例Nginx負載
- 簡單配置PostFix伺服器伺服器
- 每瓦效能提升2.6倍、機架密度升3倍,Intel 3開山之作不簡單Intel
- 高效能Web伺服器Nginx的配置與部署研究(5)Nginx配置符號Web伺服器Nginx符號
- 麒麟710效能單核跑分麒麟659提升72%單核
- Nginx的proxy_pass簡單使用記錄Nginx