Nginx效能調優總結
Nginx效能優化總結
瀏覽量:9|分類:Linux/架構,部署 | 釋出日期:2019-03-28
目錄 :
1.Gzip 壓縮
2.Expires快取時間
3.事件處理模型優化use epoll
4.高效檔案傳輸模式sendfile on
5.優化伺服器域名的散列表大小
6.優化worker服務程序數
7.FastCGI引數調優
8.Log日誌優化
9.資源防盜鏈
10.限制HTTP的請求方法
11.控制客戶端請求速率
12.HTTPS配置優化
13.優化配置及詳細註釋事例
Gzip壓縮:
#修改配置為 gzip on; #開啟gzip壓縮功能 gzip_min_length 10k; #設定允許壓縮的頁面最小位元組數; 這裡表示如果檔案小於10個位元組,就不用壓縮,因為沒有意義,本來就很小. gzip_buffers 4 16k; #設定壓縮緩衝區大小,此處設定為4個16K記憶體作為壓縮結果流快取 gzip_http_version 1.1; #壓縮版本 gzip_comp_level 2; #設定壓縮比率,最小為1,處理速度快,傳輸速度慢;9為最大壓縮比,處理速度慢,傳輸速度快; 這裡表示壓縮級別,可以是0到9中的任一個,級別越高,壓縮就越小,節省了頻寬資源,但同時也消耗CPU資源,所以一般折中為6 gzip types text/css text/xml application/javascript; #制定壓縮的型別,線上配置時儘可能配置多的壓縮型別! gzip_disable "MSIE [1-6]\."; #配置禁用gzip條件,支援正則。此處表示ie6及以下不啟用gzip(因為ie低版本不支援) gzip vary on; #選擇支援vary header;改選項可以讓前端的快取伺服器快取經過gzip壓縮的頁面; 這個可以不寫,表示在傳送資料時,給客戶端說明我使用了gzip壓縮
Nginx設定expires設定頁面快取時間
配置expires起到控制頁面快取的作用,合理的配置expires可以減少很多伺服器的請求要配置expires,
官方文件:http://nginx.org/en/docs/http/ngx_http_headers_module.html
可以在http段中或者server段中或者location段中加入
location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {root /var/www/img/;expires 30d; # 30m:30 分鐘,2h:2 小時,30d:30 天 }
控制圖片等過期時間為30天,當然這個時間可以設定的更長。具體視情況而定
事件處理模型優化use epoll
epoll用在linux上, kqueue用在bsd上, 不能物理上共存。如果你的伺服器cpu較好,linux核心新,可考慮用epoll.
events {#單個程序允許的客戶端最大連線數worker_connections20480;#收到一個新連線通知後接受盡可能多的連線。multi_accept on;#使用epoll模型use epoll; }
高效檔案傳輸模式sendfile on
引數sendfile on 用於開啟檔案高效傳輸模式,同時將tcp_nopush on 和tcp_nodelay on 兩個指令設定為on,可防止網路及磁碟I/O阻塞,提升Nginx工作效率
#開啟高效檔案傳輸模式 sendfile on; #減少網路報文段數量 tcp_nopush on; #提高I/O效能 tcp_nodelay on;
優化伺服器域名的散列表大小
如果在 server_name 中配置了一個很長的域名,那麼過載 Nginx 時會報錯,因此需要使用 server_names_hash_max_size 來解決域名過長的問題
#域名散列表大小server_names_hash_bucket_size 64; server_names_hash_max_size 2048;
優化worker服務程序數
worker程序數最開始的設定可以等於CPU的核數,高流量高併發場合也可以考慮將程序數提高至CPU核數*2, 設定太多沒有意義。
#檢視CPU總顆數: [root@nginx conf]# grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l 1 #檢視CPU總核數: [root@nginx conf]# grep processor /proc/cpuinfo |wc -l 4
#CPU的總核數4 worker_processes4;
FastCGI引數調優
如果是動態請求(如 PHP),那麼 Nginx 就會把它通過 FastCGI 介面傳送給 PHP 引擎服務, (即 php-fpm)進行解析.
fastcgi_connect_timeout 240; # Nginx伺服器和後端FastCGI伺服器連線的超時時間fastcgi_send_timeout 240; # Nginx允許FastCGI伺服器返回資料的超時時間,即在規定時間內後端伺服器必須傳完所有的資料,否則Nginx將斷開這個連線fastcgi_read_timeout 240; # Nginx從FastCGI伺服器讀取響應資訊的超時時間,表示連線建立成功後,Nginx等待後端伺服器的響應時間fastcgi_buffer_size 64k; # Nginx FastCGI 的緩衝區大小,用來讀取從FastCGI伺服器端收到的第一部分響應資訊的緩衝區大小fastcgi_buffers 4 64k; # 設定用來讀取從FastCGI伺服器端收到的響應資訊的緩衝區大小和緩衝區數量fastcgi_busy_buffers_size 128k; # 用於設定系統很忙時可以使用的 proxy_buffers 大小fastcgi_temp_file_write_size 128k; # FastCGI 臨時檔案的大小# fastcti_temp_path /data/ngx_fcgi_tmp; # FastCGI 臨時檔案的存放路徑fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g; # 快取目錄
fastcgi_cache ngx_fcgi_cache; # 快取FastCGI生成的內容,比如PHP生成的動態內容fastcgi_cache_valid 200 302 1h; # 指定http狀態碼的快取時間,這裡表示將200和302快取1小時fastcgi_cache_valid 301 1d; # 指定http狀態碼的快取時間,這裡表示將301快取1天fastcgi_cache_valid any 1m; # 指定http狀態碼的快取時間,這裡表示將其他狀態碼快取1分鐘fastcgi_cache_min_uses 1; # 設定請求幾次之後響應被快取,1表示一次即被快取fastcgi_cache_use_stale error timeout invalid_header http_500; # 定義在哪些情況下使用過期快取fastcgi_cache_key http://$host$request_uri; # 定義 fastcgi_cache 的 key
Log日誌優化
1. 排除不需要的日誌。
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ {access_log off; }
2. 日誌切割:nginx日誌預設不做處理,都會存放到access.log,error.log, 導致越積越多。 可寫個定時指令碼按天儲存,每天凌晨00:00執行
#!/bin/bash YESTERDAY=$(date -d "yesterday" +"%Y-%m-%d")LOGPATH=/usr/local/openresty/nginx/logs/PID=${LOGPATH}nginx.pidmv ${LOGPATH}access.log ${LOGPATH}access-${YESTERDAY}.logmv ${LOGPATH}error.log ${LOGPATH}error-${YESTERDAY}.logkill -USR1 `cat ${PID}`
資源防盜鏈
大量的盜鏈對於伺服器也是很大的消耗, 防盜鏈主要兩種方法:
1. 根據 HTTP referer 實現防盜鏈
#第一種,匹配字尾 location ~ .*\.(gif|jpg|jpeg|png|bm|swf|flv|rar|zip|gz|bz2)$ {# 指定需要使用防盜鏈的媒體資源access_logoff;# 不記錄防盜鏈的日誌expires15d;# 設定快取時間valid_referersnoneblocked*.test.com*.abc.com;# 表示這些地址可以訪問上面的媒體資源if ($invalid_referer) {# 如果地址不如上面指定的地址就返回403return 403} }
2. 根據 cookie 實現防盜鏈:cookie 是伺服器貼在客戶端身上的 "標籤" ,伺服器用它來識別客戶端
#第二種,繫結目錄 location /images {root /web/www/img;vaild_referers nono blocked *.spdir.com *.spdir.top;if ($invalid_referer) {return 403;} }
限制HTTP的請求方法
HTTP1.1定義了八種主要的方法,其中OPTIONS、DELETE等方法在生產環境可以被認為是不安全的,因此需要配置Nginx實現限制指定某些HTTP請求的方法來達到提升伺服器安全的目的。
if ($request_method !~ ^(GET|HEAD|POST)$ ) {return 501; }
通過限制上傳伺服器的Web服務(可以具體到檔案)使用GET方法,防止使用者通過上傳伺服器訪問儲存內容
if ($request_method !~ ^(GET)$ ) {return 501; }
控制客戶端請求速率
# 以請求的客戶端IP作為key值,記憶體區域命名為one,分配10m記憶體空間,訪問速率限制為1秒1次請求 limit_req_zone $binary_remove_addr zone=one:10m rate=1r/s; # 使用前面定義的為one的記憶體空間,佇列值為5,即可以有5個請求排隊等候 limit_reqzone=one burst=5;
HTTPS配置優化
NGINX配置HTTPS效能優化方案一則:
1) HSTS的合理使用
2) 會話恢復的合理使用
3) Ocsp stapling的合理使用
4) TLS協議的合理配置
5) False Start的合理使用
6) SNI功能的合理使用,
7) HTTP 2.0的合理使用(Nginx在1.9.x版本就開始支援http2協議)
8) SSL硬體加速卡合理使用
#以下是一個nginx優化https的配置模板: server {# 把ssl on;這行去掉,ssl寫在443埠後面。這樣http和https的連結都可以用listen 443 ssl http2 default_server;server_namesite.xxx.com;# HSTS的合理使用,max-age表明HSTS在瀏覽器中的快取時間,includeSubdomainscam引數指定應該在所有子域上啟用HSTS,preload引數表示預載入,通過Strict-Transport-Security: max-age=0將快取設定為0可以撤銷HSTSadd_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";ssl_certificate /usr/local/nginx/cert/server.pem;ssl_certificate_key /usr/local/nginx/cert/server.key;# 分配10MB的共享記憶體快取,不同工作程序共享TLS會話資訊ssl_session_cache shared:SSL:10m;# 設定會話快取過期時間24hssl_session_timeout 1440m;# TLS協議的合理配置# 指定TLS協議的版本,不安全的SSL2和SSL3要廢棄掉ssl_protocols TLSv1 TLSv1.1 TLSv1.2;# 啟用ssl_prefer_server_ciphers,用來告訴Nginx在TLS握手時啟用伺服器演算法優先,由伺服器選擇適配演算法而不是客戶端ssl_prefer_server_ciphers on;# 優先選擇支援前向加密的演算法,且按照效能的優先順序排列ssl_ciphers ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES256-SHA384 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA ECDHE-ECDSA-DES-CBC3-SHA ECDHE-RSA-DES-CBC3-SHA EDH-RSA-DES-CBC3-SHA AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-SHA256 AES256-SHA256 AES128-SHA AES256-SHA DES-CBC3-SHA !DSS";# 會話恢復的合理使用# 配置會話票證,減少了TLS握手的開銷ssl_session_tickets on;# 生產key的命令通過openssl生成:openssl rand –out session_ticket.key 48ssl_session_ticket_key /usr/local/nginx/ssl_cert/session_ticket.key;#設定TLS日誌格式log_format ssl "$time_local $server_name $remote_addr $connection $connnection_requests $ssl_protocol $ssl_cipher $ssl_session_id $ssl_session_reused";access_log /usr/local/nginx/logs/access.log ssl;# Ocsp stapling的合理使用# 啟用OCSP stapling,指定更新檔案內容,無需從服務商拉取ssl_stapling on;ssl_stapling_file /usr/local/nginx/oscp/stapling_file.ocsp;# 或者不指定更新檔案內容,線上獲取,valid表示快取5分鐘,resolver_timeout表示網路超時時間#resolver 8.8.8.8 8.8.4.4 223.5.5.5 valid=300s;#resolver_timeout 5s;# 啟用OCSP響應驗證,OCSP資訊響應適用的證書ssl_stapling_verify on;ssl_trusted_certificate /usr/local/nginx/ssl_cert/trustchain.crt;roothtml;indexindex.html index.htm;location / {...}error_page 403 /403.html;location = /403.html {root /usr/local/nginx/waf/403/default;}error_page 500 502 503 504 /502.html;location = /502.html {root /usr/local/nginx/waf/403/default;} }
優化配置及詳細註釋事例
#普通配置 #==效能配置#執行使用者 user nobody; #pid檔案 pid logs/nginx.pid;#Nginx基於事件的非阻塞多路複用模型(epoll或kquene) #一個程序在短時間內可以響應大量請求,工作程序設定與cpu數相同,避免cpu在多個程序間切換增加開銷 #==worker程序數,通常設定<=CPU數量,auto為自動檢測,一般設定最大8個即可,再大效能提升較小或不穩定 worker_processes auto;#==將每個程序繫結到特定cpu上,避免程序在cpu間切換的開銷 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;#==worker程序開啟最大檔案數,可CPU*10000設定,或設定系統最大數量655350 worker_rlimit_nofile 102400; #全域性錯誤日誌 error_loglogs/error.log;#events模組中包含nginx中所有處理連線的設定,併發響應能力的關鍵配置 events {#==每個程序同時開啟的最大連線數(最大併發數)worker_connections 102400;#==告訴nginx收到一個新連結通知後接受盡可能多的連結#multi_accept on;#一般http 1.1協議下,瀏覽器預設使用兩個併發連結#如果是反向代理,nginx需要和客戶端保持連線,還需要和後端伺服器保持連線#Http伺服器時,設定max_client=worker_processes*worker_connections/2#反向代理時,設定max_client=worker_processes*worker_connections/4#==最大可用客戶端數#max_client#==使用非阻塞模型,設定複用客戶端執行緒的輪訓方法use epoll; }#http模組控制著nginx http處理的所有核心特性 http {#開啟或關閉錯誤頁面中的nginx版本號等資訊server_tokens on;#!server_tag on;#!server_info on;#==優化磁碟IO設定,指定nginx是否呼叫sendfile函式來輸出檔案,普通應用設為on,下載等磁碟IO高的應用,可設為offsendfile on;#快取傳送請求,啟用如下兩個配置,會在資料包達到一定大小後再發送資料#這樣會減少網路通訊次數,降低阻塞概率,但也會影響響應的及時性#比較適合於檔案下載這類的大資料包通訊場景#tcp_nopush on;#tcp_nodelay on;#==設定nginx是否儲存訪問日誌,關閉這個可以讓讀取磁碟IO操作更快access_log on;#設定nginx只記錄嚴重錯誤,可減少IO壓力#error_log logs/error.log crit;#Http1.1支援長連線#降低每個連結的alive時間可在一定程度上提高響應連線數量#==給客戶端分配keep-alive連結超時時間keepalive_timeout 30;#設定使用者儲存各種key的共享記憶體的引數,5m指的是5兆limit_conn_zone $binary_remote_addr zone=addr:5m;#為給定的key設定最大的連線數,這裡的key是addr,設定的值是100,就是說允許每一個IP地址最多同時開啟100個連線limit_conn addr 100;#include指在當前檔案中包含另一個檔案內容include mime.types;#設定檔案使用預設的mine-typedefault_type text/html;#設定預設字符集charset UTF-8;#==設定nginx採用gzip壓縮的形式傳送資料,減少傳送資料量,但會增加請求處理時間及CPU處理時間,需要權衡gzip on;#==加vary給代理伺服器使用,針對有的瀏覽器支援壓縮,有個不支援,根據客戶端的HTTP頭來判斷是否需要壓縮gzip_vary on;#nginx在壓縮資源之前,先查詢是否有預先gzip處理過的資源#!gzip_static on;#為指定的客戶端禁用gzip功能gzip_disable "MSIE[1-6]\.";#允許或禁止壓縮基於請求和相應的響應流,any代表壓縮所有請求gzip_proxied any;#==啟用壓縮的最少位元組數,如果請求小於1024位元組則不壓縮,壓縮過程會消耗系統資源gzip_min_length 1024;#==資料壓縮等級,1-9之間,9最慢壓縮比最大,壓縮比越大對系統性能要求越高gzip_comp_level 2;#需要壓縮的資料格式gzip_types text/plain text/css text/xml text/javascriptapplication/json application/x-javascript application/xml application/xml+rss;#靜態檔案快取#==開啟快取的同時也指定了快取檔案的最大數量,20s如果檔案沒有被請求則刪除快取open_file_cache max=100000 inactive=20s;#==多長時間檢查一次快取的有效期open_file_cache_valid 30s;#==有效期內快取檔案最小的訪問次數,只有訪問超過2次的才會被快取open_file_cache_min_uses 2;#當搜尋一個檔案時是否快取錯誤資訊open_file_cache_errors on;#==允許客戶端請求的最大單檔案位元組數client_max_body_size 4m;#==客戶端請求頭緩衝區大小client_header_buffer_size 4k;#是否啟用對傳送給客戶端的URL進行修改proxy_redirect off;#後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IPproxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#==nginx跟後端伺服器連線超時時間(代理連線超時)proxy_connect_timeout 60;#==連線成功後,後端伺服器響應時間(代理接收超時)proxy_read_timeout 120;#==後端伺服器資料回傳時間(代理髮送超時)proxy_send_timeout 20;#==設定代理伺服器(nginx)儲存使用者頭資訊的緩衝區大小proxy_buffer_size 32k;#==proxy_buffers緩衝區,網頁平均在32k以下的設定proxy_buffers 4 128k;#==高負荷下緩衝大小(proxy_buffers*2)proxy_busy_buffers_size 256k;#==設定快取資料夾大小,大於這個值,將從upstream伺服器傳proxy_temp_file_write_size 256k;#==1G記憶體緩衝空間,3天不用刪除,最大磁碟緩衝空間2Gproxy_cache_path /home/cache levels=1:2 keys_zone=cache_one:1024m inactive=3d max_size=2g;#設定負載均衡伺服器列表upstream nginx.test.com{#後端伺服器訪問規則#ip_hash;#weight引數表示權重值,權值越高被分配到的機率越大#server 10.11.12.116:80 weight=5;#PC_Localserver 10.11.12.116:80;#PC_Serverserver 10.11.12.112:80;#Notebook#server 10.11.12.106:80;}#server代表虛擬主機,可以理解為站點(掛載多個站點,只需要配置多個server及upstream節點即可)server {#監聽80埠listen 80;#識別的域名,定義使用nginx.test.com訪問server_name nginx.test.com;#設定本虛擬主機的訪問日誌access_log logs/nginx.test.com.access.log;#一個域名下匹配多個URI的訪問,使用location進行區分,後面緊跟著的/代表匹配規則#如動態資源訪問和靜態資源訪問會分別指向不同的位置的應用場景## 基本語法規則:location [=|~|~*|^~] /uri/ {...}# = 開頭表示精確匹配# ^~ 開頭表示uri以某個常規字串開頭,匹配成功後不再進行正則匹配# ~ 開頭表示區分大小寫的正則匹配# ~* 開頭表示不區分大小寫的正則匹配# !~ 開頭表示區分大小寫的不匹配的正則# !~* 開頭表示不區分大小寫的不匹配的正則# / 通用匹配,任何請求都會被匹配到## 理解如下:# 有兩種匹配模式:普通字串匹配,正則匹配# 無開頭引導字元或以=開頭表示普通字串匹配# 以~或~*開頭表示正則匹配,~*表示不區分大小寫# 【多個location時,先匹配普通字串location,再匹配正則location】# 只識別URI部分,例如請求為“/test/1/abc.do?arg=xxx”# (1)先查詢是否有=開頭的精確匹配,即“location=/test/1/abc.do {...}”# (2)再查詢普通匹配,以“最大字首”為規則,如有以下兩個location#location /test/ {...}#location /test/1/ {...}#則匹配後一項# (3)匹配到一個普通location後,搜尋並未結束,而是暫存當前結果,並繼續進行正則搜尋# (4)在所有正則location中找到第一個匹配項後,以此匹配項為最終結果# 【所以正則匹配項,匹配規則受定義前後順序影響,但普通匹配不會】# (5)如果未找到正則匹配項,則以(3)中快取的結果為最終結果# (6)如果一個匹配都沒有,則返回404# location =/ {...}與location / {...}的差別# 前一個是精確匹配,只響應“/”的請求,所有“/xxx”形式的請求不會以“字首匹配形式”匹配到它# 後一個正相反,所有請求必然都是以“/”開頭,所以沒有其他匹配結果時一定會執行到它# location ^~ / {...} ^~的意思是禁止正則匹配,表示匹配到此項後不再進行後續的正則搜尋# 相當於普通匹配模式匹配成功後就以此結果為最終結果,停止進行後續的正則匹配location / {#定義伺服器的預設網站根目錄位置,可以寫相對路徑,也可以寫絕對路徑root html;#定義首頁索引檔案的名稱index index.html index.htm;#定義轉發後端負載伺服器組proxy_pass http://nginx.test.com;}#定義錯誤提示頁面error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}#靜態檔案,nginx自己處理location ~ ^/(images|javascript|js|css|flash|media|static)/{root /var/www/virtual/htdocs;#過期時間1天expires 1d;#關閉媒體檔案日誌access_log off;log_not_found off;}#設定檢視Nginx狀態的地址location /NginxStatus {#!stub_status on; #無此關鍵字access_log off;auth_basic "NginxStatus";auth_basic_user_file conf/htpasswd;}#禁止訪問的檔案.htxxxlocation ~ /\.ht {#deny all;禁止訪問,返回403deny all;#allow all;允許訪問}}#網站較多的情況下ngxin又不會請求瓶頸可以考慮掛多個站點,並把虛擬主機配置單獨放在一個檔案內,引入進來#include website.conf; }
上一篇:NodeJS原始碼解析 - HTTP Server模組
下一篇: 沒有了