11 个 Nginx 参数性能优化工作
工作上,需要配置 Nginx,要投入生產(chǎn)使用,做了一點(diǎn)優(yōu)化工作,加上以前也經(jīng)常折騰 Nginx,故記下一些優(yōu)化工作。
優(yōu)化 Nginx 進(jìn)程數(shù)量
配置參數(shù)如下:
worker_processes 1; # 指定 Nginx 要開啟的進(jìn)程數(shù),結(jié)尾的數(shù)字就是進(jìn)程的個(gè)數(shù),可以為 auto這個(gè)參數(shù)調(diào)整的是 Nginx 服務(wù)的 worker 進(jìn)程數(shù),Nginx 有 Master 進(jìn)程和 worker 進(jìn)程之分,Master 為管理進(jìn)程、真正接待“顧客”的是 worker 進(jìn)程。
進(jìn)程個(gè)數(shù)的策略:worker 進(jìn)程數(shù)可以設(shè)置為等于 CPU 的核數(shù)。高流量高并發(fā)場合也可以考慮將進(jìn)程數(shù)提高至 CPU 核數(shù) x 2。這個(gè)參數(shù)除了要和 CPU 核數(shù)匹配之外,也與硬盤存儲的數(shù)據(jù)及系統(tǒng)的負(fù)載有關(guān),設(shè)置為 CPU 核數(shù)是個(gè)好的起始配置,也是官方建議的。
當(dāng)然,如果想省麻煩也可以配置為worker_processes auto;,將由 Nginx 自行決定 worker 數(shù)量。當(dāng)訪問量快速增加時(shí),Nginx 就會臨時(shí) fork 新進(jìn)程來縮短系統(tǒng)的瞬時(shí)開銷和降低服務(wù)的時(shí)間。
將不同的進(jìn)程綁定到不同的CPU
默認(rèn)情況下,Nginx 的多個(gè)進(jìn)程有可能運(yùn)行在同一個(gè) CPU 核上,導(dǎo)致 Nginx 進(jìn)程使用硬件的資源不均,這就需要制定進(jìn)程分配到指定的 CPU 核上處理,達(dá)到充分有效利用硬件的目的。配置參數(shù)如下:
worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000;其中 worker_cpu_affinity 就是配置 Nginx 進(jìn)程與 CPU 親和力的參數(shù),即把不同的進(jìn)程分給不同的 CPU 核處理。這里的0001 0010 0100 1000是掩碼,分別代表第1、2、3、4核CPU。上述配置會為每個(gè)進(jìn)程分配一核CPU處理。
當(dāng)然,如果想省麻煩也可以配置worker_cpu_affinity auto;,將由 Nginx 按需自動分配。
Nginx 事件處理模型優(yōu)化
Nginx 的連接處理機(jī)制在不同的操作系統(tǒng)中會采用不同的 I/O 模型,在 linux 下,Nginx 使用 epoll 的 I/O 多路復(fù)用模型,在 Freebsd 中使用 kqueue 的 I/O 多路復(fù)用模型,在 Solaris 中使用 /dev/poll 方式的 I/O 多路復(fù)用模型,在 Windows 中使用 icop,等等。
配置如下:
events {use epoll; }events 指令是設(shè)定 Nginx 的工作模式及連接數(shù)上限。use指令用來指定 Nginx 的工作模式。Nginx 支持的工作模式有 select、 poll、 kqueue、 epoll 、 rtsig 和/ dev/poll。當(dāng)然,也可以不指定事件處理模型,Nginx 會自動選擇最佳的事件處理模型。
單個(gè)進(jìn)程允許的客戶端最大連接數(shù)
通過調(diào)整控制連接數(shù)的參數(shù)來調(diào)整 Nginx 單個(gè)進(jìn)程允許的客戶端最大連接數(shù)。
events {worker_connections 20480; }worker_connections 也是個(gè)事件模塊指令,用于定義 Nginx 每個(gè)進(jìn)程的最大連接數(shù),默認(rèn)是 1024。
最大連接數(shù)的計(jì)算公式如下:
max_clients = worker_processes * worker_connections;
如果作為反向代理,因?yàn)闉g覽器默認(rèn)會開啟 2 個(gè)連接到 server,而且 Nginx 還會使用fds(file descriptor)從同一個(gè)連接池建立連接到 upstream 后端。則最大連接數(shù)的計(jì)算公式如下:
max_clients = worker_processes * worker_connections / 4;
另外,進(jìn)程的最大連接數(shù)受 Linux 系統(tǒng)進(jìn)程的最大打開文件數(shù)限制,在執(zhí)行操作系統(tǒng)命令 ulimit -HSn 65535或配置相應(yīng)文件后, worker_connections 的設(shè)置才能生效。
配置獲取更多連接數(shù)
默認(rèn)情況下,Nginx 進(jìn)程只會在一個(gè)時(shí)刻接收一個(gè)新的連接,我們可以配置multi_accept 為 on,實(shí)現(xiàn)在一個(gè)時(shí)刻內(nèi)可以接收多個(gè)新的連接,提高處理效率。該參數(shù)默認(rèn)是 off,建議開啟。
events {multi_accept on; }配置 worker 進(jìn)程的最大打開文件數(shù)
調(diào)整配置 Nginx worker 進(jìn)程的最大打開文件數(shù),這個(gè)控制連接數(shù)的參數(shù)為 worker_rlimit_nofile。該參數(shù)的實(shí)際配置如下:
worker_rlimit_nofile 65535;可設(shè)置為系統(tǒng)優(yōu)化后的 ulimit -HSn 的結(jié)果
優(yōu)化域名的散列表大小
http {server_names_hash_bucket_size 128; }參數(shù)作用:設(shè)置存放域名( server names)的最大散列表的存儲桶( bucket)的大小。 默認(rèn)值依賴 CPU 的緩存行。
server_names_hash_bucket_size 的值是不能帶單位 的。配置主機(jī)時(shí)必須設(shè)置該值,否則無法運(yùn)行 Nginx,或者無法通過測試 。 該設(shè)置與 server_ names_hash_max_size 共同控制保存服務(wù)器名的 hash 表, hash bucket size 總是等于 hash 表的大小, 并且是一路處理器緩存大小的倍數(shù)。若 hash bucket size 等于一路處理器緩存的大小,那么在查找鍵時(shí), 最壞的情況下在內(nèi)存中查找的次數(shù)為 2。第一次是確定存儲單元的地址,第二次是在存儲單元中查找鍵值 。 若報(bào) 出 hash max size 或 hash bucket size 的提示,則需要增加 server_names_hash_max size 的值。
TCP 優(yōu)化
http {sendfile on;tcp_nopush on;keepalive_timeout 120;tcp_nodelay on; }第一行的 sendfile 配置可以提高 Nginx 靜態(tài)資源托管效率。sendfile 是一個(gè)系統(tǒng)調(diào)用,直接在內(nèi)核空間完成文件發(fā)送,不需要先 read 再 write,沒有上下文切換開銷。
TCP_NOPUSH 是 FreeBSD 的一個(gè) socket 選項(xiàng),對應(yīng) Linux 的 TCP_CORK,Nginx 里統(tǒng)一用 tcp_nopush 來控制它,并且只有在啟用了 sendfile 之后才生效。啟用它之后,數(shù)據(jù)包會累計(jì)到一定大小之后才會發(fā)送,減小了額外開銷,提高網(wǎng)絡(luò)效率。
TCP_NODELAY 也是一個(gè) socket 選項(xiàng),啟用后會禁用 Nagle 算法,盡快發(fā)送數(shù)據(jù),某些情況下可以節(jié)約 200ms(Nagle 算法原理是:在發(fā)出去的數(shù)據(jù)還未被確認(rèn)之前,新生成的小數(shù)據(jù)先存起來,湊滿一個(gè) MSS 或者等到收到確認(rèn)后再發(fā)送)。Nginx 只會針對處于 keep-alive 狀態(tài)的 TCP 連接才會啟用 tcp_nodelay。
優(yōu)化連接參數(shù)
http {client_header_buffer_size 32k;large_client_header_buffers 4 32k;client_max_body_size 1024m;client_body_buffer_size 10m; }這部分更多是更具業(yè)務(wù)場景來決定的。例如client_max_body_size用來決定請求體的大小,用來限制上傳文件的大小。上面列出的參數(shù)可以作為起始參數(shù)。
配置壓縮優(yōu)化
9.1、Gzip 壓縮
我們在上線前,代碼(JS、CSS 和 HTML)會做壓縮,圖片也會做壓縮(PNGOUT、Pngcrush、JpegOptim、Gifsicle 等)。對于文本文件,在服務(wù)端發(fā)送響應(yīng)之前進(jìn)行 GZip 壓縮也很重要,通常壓縮后的文本大小會減小到原來的 1/4 - 1/3。
http {gzip on;gzip_buffers 16 8k;gzip_comp_level 6;gzip_http_version 1.0;gzip_min_length 1000;gzip_proxied any;gzip_vary on;gzip_typestext/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xmltext/javascript application/javascript application/x-javascripttext/x-json application/json application/x-web-app-manifest+jsontext/css text/plain text/x-componentfont/opentype application/x-font-ttf application/vnd.ms-fontobjectimage/x-icon;gzip_disable "MSIE [1-6]\.(?!.*SV1)"; }這部分內(nèi)容比較簡單,只有兩個(gè)地方需要解釋下:
gzip_vary 用來輸出 Vary 響應(yīng)頭,用來解決某些緩存服務(wù)的一個(gè)問題,詳情請看我之前的博客:HTTP 協(xié)議中 Vary 的一些研究。
gzip_disable 指令接受一個(gè)正則表達(dá)式,當(dāng)請求頭中的 UserAgent 字段滿足這個(gè)正則時(shí),響應(yīng)不會啟用 GZip,這是為了解決在某些瀏覽器啟用 GZip 帶來的問題。
默認(rèn) Nginx 只會針對 HTTP/1.1 及以上的請求才會啟用 GZip,因?yàn)椴糠衷缙诘?HTTP/1.0 客戶端在處理 GZip 時(shí)有 Bug。現(xiàn)在基本上可以忽略這種情況,于是可以指定 gzip_http_version 1.0 來針對 HTTP/1.0 及以上的請求開啟 GZip。
9.2、Brotli 壓縮
Brotli 是基于LZ77算法的一個(gè)現(xiàn)代變體、霍夫曼編碼和二階上下文建模。Google軟件工程師在2015年9月發(fā)布了包含通用無損數(shù)據(jù)壓縮的Brotli增強(qiáng)版本,特別側(cè)重于HTTP壓縮。其中的編碼器被部分改寫以提高壓縮比,編碼器和解碼器都提高了速度,流式API已被改進(jìn),增加更多壓縮質(zhì)量級別。
需要安裝libbrotli 、ngx_brotli ,重新編譯 Nginx 時(shí),帶上--add-module=/path/to/ngx_brotli即可,然后配置如下
http {brotli on;brotli_comp_level 6;brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml; }Brotli 可與 Gzip 共存在一個(gè)配置文件中
靜態(tài)資源優(yōu)化
靜態(tài)資源優(yōu)化,可以減少連接請求數(shù),同時(shí)也不需要對這些資源請求打印日志。但副作用是資源更新可能無法及時(shí)。
server {# 圖片、視頻location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {expires 30d;access_log off;}# 字體location ~ .*\.(eot|ttf|otf|woff|svg)$ {expires 30d;access_log off;}# js、csslocation ~ .*\.(js|css)?$ {expires 7d;access_log off;} }收官~
首發(fā)于 https://www.linpx.com
總結(jié)
以上是生活随笔為你收集整理的11 个 Nginx 参数性能优化工作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qtum 量子链跨链原子激活 实现 QT
- 下一篇: 细说 Nginx: 负载均衡 Load