1. 程式人生 > 其它 >Nginx調優

Nginx調優

Nginx調優

前言:

  最近相對比較閒,整理下以前工作中學到的東西,將接觸到生產環境中的內容都深入學習一下,nginx與tomcat的優化是在山西ott專案上接觸到的,直接操作配置檔案很容易,但更多的配置引數與優化方式還是需要了解的,先得知道問題在哪裡,然後再做。

Nginx調優

目錄

軟體調優
1.隱藏 Nginx 版本號
2.隱藏 Nginx 版本號和軟體名
3.更改 Nginx 服務的預設使用者
4.優化 Nginx worker 程序數
5.繫結 Nginx 程序到不同的 CPU 上
6.優化 Nginx 處理事件模型
7.優化 Nginx 單個程序允許的最大連線數


8.優化 Nginx worker 程序最大開啟檔案數
9.優化伺服器域名的散列表大小
10.開啟高效檔案傳輸模式
11.優化 Nginx 連線超時時間
12.限制上傳檔案的大小
13.FastCGI 相關引數調優
14.配置 Nginx gzip 壓縮
15.配置 Nginx expires 快取
16.優化 Nginx日誌(日誌切割)
17.優化 Nginx 站點目錄
18.配置 Nginx 防盜鏈
19.配置 Nginx 錯誤頁面優雅顯示
20.優化 Nginx 檔案許可權
21.Nginx 防爬蟲優化
22.控制 Nginx 併發連線數
23. 叢集代理優化

系統核心引數優化

Nginx軟體調優

1.隱藏 Nginx 版本號

為什麼要隱藏 Nginx 版本號:一般來說,軟體的漏洞都與版本有關,隱藏版本號是為了防止惡意使用者利用軟體漏洞進行攻擊

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf worker_processes 1; events { worker_connections 1024; }
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; # 隱藏版本號 server { listen 80; server_name www.abc.com; location / { root html/www; index index.html index.htm; } } } ... [root@localhost ~]# /usr/local/nginx/sbin/nginx -t [root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload [root@localhost ~]# curl -I 127.0.0.1 # 檢視是否隱藏版本號 HTTP/1.1 404 Not Found Server: nginx Date: Thu, 25 May 2017 05:23:03 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive

2.隱藏 Nginx 版本號和軟體名

為什麼要隱藏 Nginx 版本號和軟體名:一般來說,軟體的漏洞都與版本有關,隱藏版本號是為了防止惡意使用者利用軟體漏洞進行攻擊,而軟體名可以進行修改,否則黑客知道是 Nginx 伺服器更容易進行攻擊,需要注意的是,隱藏 Nginx 軟體名需要重新編譯安裝 Nginx ,如果沒有該方面需求儘量不要做

1) 修改:/usr/local/src/nginx-1.6.3/src/core/nginx.h

?
1 2 3 #define NGINX_VERSION "8.8.8.8" # 修改為想要顯示的版本號 #define NGINX_VER "Google/" NGINX_VERSION # 修改為想要顯示的軟體名 #define NGINX_VAR "Google" # 修改為想要顯示的軟體名

2) 修改:/usr/local/src/nginx-1.6.3/src/http/ngx_http_header_filter_module.c

?
1 2 static char ngx_http_server_string[] = "Server: Google" CRLF; # 修改為想要顯示的軟體名 static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;

3) 修改:/usr/local/src/nginx-1.6.3/src/http/ngx_http_special_response.c

?
1 2 3 4 5 6 7 8 9 10 11 static u_char ngx_http_error_full_tail[] = "<hr><center>" NGINX_VER "(www.google.com)</center>" CRLF # 此行定義對外展示的內容 "</body>" CRLF "</html>" CRLF ; static u_char ngx_http_error_tail[] = "<hr><center>Google</center>" CRLF # 此行定義對外展示的軟體名 "</body>" CRLF "</html>" CRLF ;

4) 重新編譯 Nginx

?
1 2 3 4 cd /usr/local/src/nginx-1.6.3 ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module make && make install /usr/local/nginx/sbin/nginx

3.更改 Nginx 服務的預設使用者

為什麼要更改 Nginx 服務的預設使用者:就像更改 ssh 的預設 22 埠一樣,增加安全性,Nginx 服務的預設使用者是 nobody ,我們更改為 nginx
1) 新增 nginx 使用者

?
1 useradd -s /sbin/nologin -M nginx

2) 更改 Nginx 配置檔案

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf worker_processes 1; user nginx nginx; # 指定Nginx服務的使用者和使用者組 events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; server { listen 80; server_name www.abc.com; location / { root html/www; index index.html index.htm; } } }

3) 重新載入 Nginx

?
1 2 [root@localhost ~]# /usr/local/nginx/sbin/nginx -t [root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload

4) 驗證是否生效

?
1 2 3 [root@localhost ~]# ps aux | grep nginx root 8901 0.0 0.1 45036 1784 ? Ss 13:54 0:00 nginx: master process /usr/local/nginx/sbin/nginx nginx 8909 0.0 0.1 45460 1828 ? S 13:59 0:00 nginx: worker process # Nginx程序的所屬使用者為nginx

4.優化 Nginx worker 程序數

Nginx 有 Master 和 worker 兩種程序,Master 程序用於管理 worker 程序,worker 程序用於 Nginx 服務

worker 程序數應該設定為等於 CPU 的核數,高流量併發場合也可以考慮將程序數提高至 CPU 核數 * 2

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@localhost ~]# grep -c processor /proc/cpuinfo # 檢視CPU核數 2 [root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf # 設定worker程序數 worker_processes 2; user nginx nginx; ...... [root@localhost ~]# /usr/local/nginx/sbin/nginx -t # 重新載入Nginx [root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload [root@localhost ~]# ps -ef | grep nginx | grep -v grep # 驗證是否為設定的程序數 root 8901 1 0 13:54 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx nginx 8937 8901 0 14:14 ? 00:00:00 nginx: worker process nginx 8938 8901 0 14:14 ? 00:00:00 nginx: worker process

5.繫結 Nginx 程序到不同的 CPU 上

為什麼要繫結 Nginx 程序到不同的 CPU 上 :預設情況下,Nginx 的多個程序有可能跑在某一個 CPU 或 CPU 的某一核上,導致 Nginx 程序使用硬體的資源不均,因此繫結 Nginx 程序到不同的 CPU 上是為了充分利用硬體的多 CPU 多核資源的目的。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@localhost ~]# grep -c processor /proc/cpuinfo # 檢視CPU核數 2 worker_processes 2; # 2核CPU的配置 worker_cpu_affinity 01 10; worker_processes 4; # 4核CPU的配置 worker_cpu_affinity 0001 0010 0100 1000; worker_processes 8; # 8核CPU的配置 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 1000000; [root@localhost ~]# /usr/local/nginx/sbin/nginx -t [root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
?
1 2 3 4 5 6 7 8 [root@localhost ~]# cd /usr/local/src/ # 進行壓力測試,教程:http://os.51cto.com/art/201202/317803.htm [root@localhost src]# wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz [root@localhost src]# tar -zxvf webbench-1.5.tar.gz [root@localhost src]# cd webbench-1.5 [root@localhost src]# yum install -y ctags gcc [root@localhost src]# mkdir -m 644 -p /usr/local/man/man1 [root@localhost src]# make && make install [root@localhost src]# webbench -c 10000 -t 60 http://192.168.5.131/
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@localhost ~]# top # 按1檢視CPU排程結果,這裡是虛擬機器測試,效果並不太明顯 top - 14:44:46 up 4:40, 3 users, load average: 0.01, 0.32, 0.24 Tasks: 85 total, 1 running, 84 sleeping, 0 stopped, 0 zombie Cpu0 : 0.8%us, 0.8%sy, 0.0%ni, 97.9%id, 0.3%wa, 0.0%hi, 0.2%si, 0.0%st Cpu1 : 0.6%us, 0.7%sy, 0.0%ni, 98.1%id, 0.0%wa, 0.0%hi, 0.5%si, 0.0%st Mem: 1534840k total, 304824k used, 1230016k free, 3932k buffers Swap: 204792k total, 0k used, 204792k free, 191364k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4319 root 20 0 98308 3932 2964 S 3.2 0.3 0:15.76 sshd 18989 root 20 0 15016 1292 1008 R 1.6 0.1 0:00.04 top 1 root 20 0 19232 1388 1112 S 0.0 0.1 0:02.19 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.08 kthreadd 3 root RT 0 0 0 0 S 0.0 0.0 0:00.61 migration/0 4 root 20 0 0 0 0 S 0.0 0.0 0:03.60 ksoftirqd/0 5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 6 root RT 0 0 0 0 S 0.0 0.0 0:00.50 watchdog/0

6.優化 Nginx 處理事件模型

Nginx 的連線處理機制在不同的作業系統會採用不同的 I/O 模型,要根據不同的系統選擇不同的事件處理模型,可供選擇的事件處理模型有:kqueue 、rtsig 、epoll 、/dev/poll 、select 、poll ,其中 select 和 epoll 都是標準的工作模型,kqueue 和 epoll 是高效的工作模型,不同的是 epoll 用在 Linux 平臺上,而 kqueue 用在 BSD 系統中。

(1) 在 Linux 下,Nginx 使用 epoll 的 I/O 多路複用模型
(2) 在 Freebsd 下,Nginx 使用 kqueue 的 I/O 多路複用模型
(3) 在 Solaris 下,Nginx 使用 /dev/poll 方式的 I/O 多路複用模型
(4) 在 Windows 下,Nginx 使用 icop 的 I/O 多路複用模型

?
1 2 3 4 5 6 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf ...... events { use epoll; } ......

7.優化 Nginx 單個程序允許的最大連線數

(1) 控制 Nginx 單個程序允許的最大連線數的引數為 worker_connections ,這個引數要根據伺服器效能和記憶體使用量來調整
(2) 程序的最大連線數受 Linux 系統程序的最大開啟檔案數限制,只有執行了 "ulimit -HSn 65535" 之後,worker_connections 才能生效
(3) 連線數包括代理伺服器的連線、客戶端的連線等,Nginx 總併發連線數 = worker 數量 * worker_connections, 總數保持在3w左右

?
1 2 3 4 5 6 7 8 9 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf worker_processes 2; worker_cpu_affinity 01 10; user nginx nginx; events { use epoll; worker_connections 15000; } ......

8.優化 Nginx worker 程序最大開啟檔案數

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf worker_processes 2; worker_cpu_affinity 01 10; worker_rlimit_nofile 65535; # worker 程序最大開啟檔案數,可設定為優化後的 ulimit -HSn 的結果 user nginx nginx; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; server { listen 80; server_name www.abc.com; location / { root html/www; index index.html index.htm; } } }

9.優化伺服器域名的散列表大小

如下,如果在 server_name 中配置了一個很長的域名,那麼過載 Nginx 時會報錯,因此需要使用 server_names_hash_max_size 來解決域名過長的問題,該引數的作用是設定存放域名的最大散列表的儲存的大小,根據 CPU 的一級快取大小來設定。

?
1 2 3 4 5 6 7 8 server { listen 80; server_name www.abcdefghijklmnopqrst.com; # 配置一個很長的域名 location / { root html/www; index index.html index.htm; } }
?
1 2 3 [root@localhost conf]# /usr/local/nginx/sbin/nginx -t # 如果配置的域名很長會出現如下錯誤 nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64 nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
?
1 2 3 4 5 6 7 8 9 10 11 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf ...... http { include mime.types; server_names_hash_bucket_size 512; # 配置在 http 區塊,預設是 512kb ,一般設定為 cpu 一級快取的 4-5 倍,一級快取大小可以用 lscpu 命令檢視 default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; include vhosts/*.conf; }

10.開啟高效檔案傳輸模式

(1) sendfile 引數用於開啟檔案的高效傳輸模式,該引數實際上是激活了 sendfile() 功能,sendfile() 是作用於兩個檔案描述符之間的資料拷貝函式,這個拷貝操作是在核心之中的,被稱為 "零拷貝" ,sendfile() 比 read 和 write 函式要高效得多,因為 read 和 write 函式要把資料拷貝到應用層再進行操作

(2) tcp_nopush 引數用於啟用 Linux 上的 TCP_CORK socket 選項,此選項僅僅當開啟 sendfile 時才生效,tcp_nopush 引數可以允許把 http response header 和檔案的開始部分放在一個檔案裡釋出,以減少網路報文段的數量

?
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf ...... http { include mime.types; server_names_hash_bucket_size 512; default_type application/octet-stream; sendfile on; # 開啟檔案的高效傳輸模式 tcp_nopush on; # 啟用 TCP_CORK socket 選擇 tcp_nodelay on; #資料在傳輸的過程中不進快取 keepalive_timeout 65; server_tokens off; include vhosts/*.conf; }

11.優化 Nginx 連線超時時間

1. 什麼是連線超時
(1) 舉個例子,某飯店請了服務員招待顧客,但是現在飯店不景氣,因此要解僱掉一些服務員,這裡的服務員就相當於 Nginx 服務建立的連線
(2) 當伺服器建立的連線沒有接收處理請求時,可以在指定的時間內讓它超時自動退出

2. 連線超時的作用
(1) 將無用的連線設定為儘快超時,可以保護伺服器的系統資源(CPU、記憶體、磁碟)
(2) 當連線很多時,及時斷掉那些建立好的但又長時間不做事的連線,以減少其佔用的伺服器資源
(3) 如果黑客攻擊,會不斷地和伺服器建立連線,因此設定連線超時以防止大量消耗伺服器的資源
(4) 如果使用者請求了動態服務,則 Nginx 就會建立連線,請求 FastCGI 服務以及後端 MySQL 服務,設定連線超時,使得在使用者容忍的時間內返回資料

3. 連線超時存在的問題
(1) 伺服器建立新連線是要消耗資源的,因此,連線超時時間不宜設定得太短,否則會造成併發很大,導致伺服器瞬間無法響應使用者的請求
(2) 有些 PHP 站點會希望設定成短連線,因為 PHP 程式建立連線消耗的資源和時間相對要少些
(3) 有些 Java 站點會希望設定成長連線,因為 Java 程式建立連線消耗的資源和時間要多一些,這時由語言的執行機制決定的

4. 設定連線超時
(1)keepalive_timeout:該引數用於設定客戶端連線保持會話的超時時間,超過這個時間伺服器會關閉該連線
(2)client_header_timeout:該引數用於設定讀取客戶端請求頭資料的超時時間,如果超時客戶端還沒有傳送完整的 header 資料,伺服器將返回 "Request time out (408)" 錯誤
(3)client_body_timeout:該引數用於設定讀取客戶端請求主體資料的超時時間,如果超時客戶端還沒有傳送完整的主體資料,伺服器將返回 "Request time out (408)" 錯誤
(4)send_timeout:用於指定響應客戶端的超時時間,如果超過這個時間,客戶端沒有任何活動,Nginx 將會關閉連線
(5)tcp_nodelay:預設情況下當資料傳送時,核心並不會馬上傳送,可能會等待更多的位元組組成一個數據包,這樣可以提高 I/O 效能,但是,在每次只發送很少位元組的業務場景中,使用 tcp_nodelay 功能,等待時間會比較長

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf ...... http { include mime.types; server_names_hash_bucket_size 512; default_type application/octet-stream; sendfile on; keepalive_timeout 65; tcp_nodelay on; client_header_timeout 15; client_body_timeout 15; send_timeout 25; include vhosts/*.conf; }

12.限制上傳檔案的大小

client_max_body_size 用於設定最大的允許客戶端請求主體的大小,在請求首部中有 "Content-Length" ,如果超過了此配置項,客戶端會收到 413 錯誤,即請求的條目過大

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 worker_processes 2; worker_cpu_affinity 01 10; user nginx nginx; error_log logs/error.log error; events { use epoll; worker_connections 20480; } http { include mime.types; server_names_hash_bucket_size 512; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; client_max_body_size 8m; # 設定客戶端最大的請求主體大小為8M include vhosts/*.conf; }

13.FastCGI 相關引數調優

當 LNMP 組合工作時,首先是使用者通過瀏覽器輸入域名請求 Nginx Web 服務,如果請求的是靜態資源,則由 Nginx 解析返回給使用者;如果是動態請求(如 PHP),那麼 Nginx 就會把它通過 FastCGI 介面傳送給 PHP 引擎服務(即 php-fpm)進行解析,如果這個動態請求要讀取資料庫資料,那麼 PHP 就會繼續向後請求 MySQL 資料庫,以讀取需要的資料,並最終通過 Nginx 服務把獲取的資料返回給使用者,這就是 LNMP 環境的基本請求流程。

 FastCGI 介紹:CGI 通用閘道器介面,是 HTTP 伺服器與其他機器上的程式服務通訊交流的一種工具,CGI 介面的效能較差,每次 HTTP 伺服器遇到動態程式時都需要重新啟動解析器來執行解析,之後結果才會被返回 HTTP 伺服器,因此就有了 FastCGI ,FastCGI 是一個在 HTTP 伺服器和動態指令碼語言間通訊的介面,主要是把動態語言和 HTTP 伺服器分離開來,使得 HTTP 伺服器專一地處理靜態請求,提高整體效能,在 Linux 下,FastCGI 介面即為 socket ,這個 socket 可以是檔案 socket 也可以是 IP socket

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; 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; # 快取目錄 server { listen 80; server_name www.abc.com; location / { root html/www; index index.html index.htm; } location ~ .*\.(php|php5)?$ { root html/www; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; 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 } } }
?
1 2 [root@localhost ~]# pkill php-fpm [root@localhost ~]# /usr/local/php/sbin/php-fpm

14.配置 Nginx gzip 壓縮

Nginx gzip 壓縮模組提供了壓縮檔案內容的功能,使用者請求的內容在傳送到客戶端之前,Nginx 伺服器會根據一些具體的策略實施壓縮,以節約網站出口頻寬,同時加快資料傳輸效率,來提升使用者訪問體驗,需要壓縮的物件有 html 、js 、css 、xml 、shtml ,圖片和視訊儘量不要壓縮,因為這些檔案大多都是已經壓縮過的,如果再壓縮可能反而變大,另外,壓縮的物件必須大於 1KB,由於壓縮演算法的特殊原因,極小的檔案壓縮後可能反而變大

?
1 2 3 4 5 6 7 8 9 10 11 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf ...... http { gzip on; # 開啟壓縮功能 gzip_min_length 1k; # 允許壓縮的物件的最小位元組 gzip_buffers 4 32k; # 壓縮緩衝區大小,表示申請4個單位為16k的記憶體作為壓縮結果的快取 gzip_http_version 1.1; # 壓縮版本,用於設定識別HTTP協議版本 gzip_comp_level 9; # 壓縮級別,1級壓縮比最小但處理速度最快,9級壓縮比最高但處理速度最慢 gzip_types text/css text/xml application/javascript; # 允許壓縮的媒體型別 gzip_vary on; # 該選項可以讓前端的快取伺服器快取經過gzip壓縮的頁面,例如用代理伺服器快取經過Nginx壓縮的資料 }

檢查壓縮:可以用 Google 瀏覽器按 F12 檢視,也可以在 Google 瀏覽器安裝 yslow 外掛(yslow.org

15.配置 Nginx expires 快取

(1) Nginx expires 的功能就是為使用者訪問的網站內容設定一個過期時間,當用戶第一次訪問這些內容時,會把這些內容儲存在使用者瀏覽器本地,這樣使用者第二次及以後繼續訪問該網站時,瀏覽器會檢查載入已經快取在使用者瀏覽器本地的內容,就不會去伺服器下載了,直到快取的內容過期或被清除為止
(2) 不希望被快取的內容:廣告圖片、網站流量統計工具、更新很頻繁的檔案
(3) 快取日期參考:51CTO 快取 1 周,新浪快取 15 天,京東快取 25 年,淘寶快取 10 年

?
1 2 3 4 5 6 7 8 9 server { listen 80; server_name www.abc.com abc.com; root html/www; location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ # 快取的物件 { expires 3650d; # 快取的時間,3650天,即10年 } }

使用 Google 瀏覽器安裝 yslow 外掛來檢視:

16.優化 Nginx access 日誌

1. 配置日誌切割

?
1 2 3 4 5 6 7 8 [root@localhost ~]# vim /usr/local/nginx/conf/cut_nginx_log.sh #!/bin/bash savepath_log='/usr/local/clogs' nglogs='/usr/local/nginx/logs' mkdir -p $savepath_log/$(date +%Y)/$(date +%m) mv $nglogs/access.log $savepath_log/$(date +%Y)/$(date +%m)/access.$(date +%Y%m%d).log mv $nglogs/error.log $savepath_log/$(date +%Y)/$(date +%m)/error.$(date +%Y%m%d).log kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
?
1 2 [root@localhost ~]# crontab -e # 每天凌晨0點執行指令碼 0 0 * * * /bin/sh /usr/local/nginx/conf/cut_nginx_log.sh > /dev/null 2>&1

2. 不記錄不需要的訪問日誌

?
1 2 3 location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ { access_log off; }

3.設定訪問日誌的許可權

?
1 2 chown -R root.root /usr/local/nginx/logs chmod -R 700 /usr/local/nginx/logs

17.優化 Nginx 站點目錄

1.禁止解析指定目錄下的指定程式

?
1 2 3 location ~ ^/data/.*\.(php|php5|sh|pl|py)$ { # 根據實際來禁止哪些目錄下的程式,且該配置必須寫在 Nginx 解析 PHP 的配置前面 deny all; }

2.禁止訪問指定目錄

?
1 2 3 location ~ ^/data/.*\.(php|php5|sh|pl|py)$ { # 根據實際來禁止哪些目錄下的程式,且該配置必須寫在 Nginx 解析 PHP 的配置前面 deny all; }

3.限制哪些 IP 不能訪問網站

?
1 2 3 4 location ~ ^/wordpress { # 相對目錄,表示只允許 192.168.1.1 訪問網站根目錄下的 wordpress 目錄 allow 192.168.1.1/24; deny all; }

18.配置 Nginx 防盜鏈

什麼是防盜鏈:簡單地說,就是某些不法網站未經許可,通過在其自身網站程式裡非法呼叫其他網站的資源,然後在自己的網站上顯示這些呼叫的資源,使得被盜鏈的那一端消耗頻寬資源 (1) 根據 HTTP referer 實現防盜鏈:referer 是 HTTP的一個首部欄位,用於指明使用者請求的 URL 是從哪個頁面通過連結跳轉過來的

(2) 根據 cookie 實現防盜鏈:cookie 是伺服器貼在客戶端身上的 "標籤" ,伺服器用它來識別客戶端

根據 referer 配置防盜鏈:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #第一種,匹配字尾 location ~ .*\.(gif|jpg|jpeg|png|bm|swf|flv|rar|zip|gz|bz2)$ { # 指定需要使用防盜鏈的媒體資源 access_log off; # 不記錄防盜鏈的日誌 expires 15d; # 設定快取時間 valid_referers none blocked *.test.com *.abc.com; # 表示這些地址可以訪問上面的媒體資源 if ($invalid_referer) { # 如果地址不如上面指定的地址就返回403 return 403 } } #第二種,繫結目錄 location /images { root /web/www/img; vaild_referers nono blocked *.spdir.com *.spdir.top; if ($invalid_referer) { return 403; } }

19.配置 Nginx 錯誤頁面優雅顯示

?
1 2 3 4 5 6 7 8 9 10 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf ...... http { location / { root html/www; index index.html index.htm; error_page 400 401 402 403 404 405 408 410 412 413 414 415 500 501 502 503 506 = http://www.xxxx.com/error.html; # 將這些狀態碼的頁面連結到 http://www.xxxx.com/error.html ,也可以單獨指定某個狀態碼的頁面,如 error_page 404 /404.html } }

20.優化 Nginx 檔案許可權

為了保證網站不受木馬入侵,所有檔案的使用者和組都應該為 root ,所有目錄的許可權是 755 ,所有檔案的許可權是 644

?
1 2 3 [root@localhost ~]# chown -R root.root /usr/local/nginx/.... # 根據實際來調整 [root@localhost ~]# chmod 755 /usr/local/nginx/.... [root@localhost ~]# chmod 644 /usr/local/nginx/....

21.Nginx 防爬蟲優化

我們可以根據客戶端的 user-agents 首部欄位來阻止指定的爬蟲爬取我們的網站\

?
1 2 3 if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot") { return 403; }

22.控制 Nginx 併發連線數

1. 限制單個 IP 的併發連線數

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@localhost ~]# cat /usr/local/nginx/conf/nginx.conf .... http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; limit_conn_zone $binary_remote_addr zone=addr:10m; # 用於設定共享記憶體區域,addr 是共享記憶體區域的名稱,10m 表示共享記憶體區域的大小 server { listen 80; server_name www.abc.com; location / { root html/www; index index.html index.htm; limit_conn addr 1; # 限制單個IP的併發連線數為1 } } }

2.限制虛擬主機總連線數

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 .... http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; limit_conn_zone $server_name zone=perserver:10m; server { listen 80; server_name www.abc.com; location / { root html/www; index index.html index.htm; limit_conn perserver 2; # 設定虛擬主機連線數為2 } } }

23. 叢集代理優化

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 upstream bbs_com_pool{ #定義伺服器池 ip_hash; #會話保持(當伺服器叢集中沒有會話池時,且代理的是動態資料就必須寫ip_hash,反之什麼也不用寫) #fair #智慧分配(第三方,需要下載upstream_fair模組)根據後端伺服器的響應時間來排程 #url_hash #更具URL的結果來分配請求(每個url定向到同一個伺服器,提高後端快取伺服器的效率,本身不支援,需要安裝nginx_hash) #當演算法為ip_hash不能有 weight backup server 192.168.10.1:80; #預設weight為1 server 192.168.10.3:80 weight=5; #weight表示權重 server 192.168.10.4:80 down; #down:不參與本次輪詢 server 192.168.10.5:80 down backup; #backup:當任何一臺主機出現故障,將進行切換替換 server 192.168.10.6:80 max_fails=3 fail_timeout=20s; #max_fails最大失敗請求次數(預設為1),fail_timeout失敗超時時間 server 192.168.10.7:8080; }

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 stream{ upstream cluster { # hash $remote_addr consistent; //保持 session 不變,四層開啟 server 192.168.1.2:80 max_fails=3 fail_timeout=30s; server 192.168.1.3:80 max_fails=3 fail_timeout=30s; } server { listen 80; proxy_pass cluster; proxy_connect_timeout 1s; proxy_timeout 3s; } location { proxy_next_upstream http_500 http_502 http_503 error timeout invalid_header; 當發生其中任何一種錯誤,將轉交給下一個伺服器 proxy_redirect off; proxy_set_header Host &$host; #設定後端伺服器的真實地址 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded_For &proxy_add_x_forwarded_for; client_body_buffer_size 128k; #緩衝區大小,本地儲存大小 proxy_connect_timeout 90; #發起握手等待的響應時間 proxy_read_timeout 90; #建立連線後等待後端伺服器響應時間(其實是後端等候處理的時間) proxy_send_timeout 90; #給定時間內後端伺服器必須響應,否則斷開 proxy_buffer_size 4k; #proxy緩衝區大小 proxy_buffers 4 32k; #緩衝區個數和大小 proxy_busy_buffers_size 64k; #系統繁忙時buffer的臨時大小,官方要求proxy_buffer_size*2 proxy_temp_file_write_size 64k; #proxy臨時檔案的大小 } }

系統核心引數優化

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 vim /etc/sysctl.conf net.ipv4.tcp_syncookies = 1 fs.file-max = 999999 net.ipv4.tcp_max_tw_buckets = 6000 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.core.somaxconn=262114 net.core.netdev_max_backlog=262114 net.ipv4.tcp_max_syn_backlog = 262114 net.ipv4.tcp_max_orphans=262114 net.ipv4.tcp_synack_retries=1 net.ipv4.tcp_syn_retries=1 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_fin_timeout = 30 net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.tcp_rmem = 10240 87380 12582912 net.ipv4.tcp_wmem = 10240 87380 12582912 net.core.netdev_max_backlog = 8096 net.core.rmem_default = 6291456 net.core.wmem_default = 6291456 net.core.rmem_max = 12582912 net.core.wmem_max = 12582912

引數詳解

+ View Code?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 net.ipv4.tcp_syncookies = 1:選項用於設定開啟SYN cookies,當出現SYN等待佇列溢位時,啟用cookies進行處理; fs.file-max = 999999:這個引數表示程序(比如一個worker程序)可以同時開啟的最大控制代碼數,這個引數直線限制最大併發連線數,需根據實際情況配置; net.ipv4.tcp_max_tw_buckets =6000:這個引數用來設定timewait數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並列印警告資訊。該引數預設為180 000,過多的TIME_WAIT套接字會使Web伺服器變慢; net.ipv4.tcp_tw_recycle=1:這個引數用於設定啟用timewait快速回收; net.ipv4.tcp_tw_reuse = 1:這個引數設定為1,表示允許將TIME-WAIT狀態的socket重新用於新的TCP連線,這對於伺服器來說很有意義,因為伺服器上總會有大量TIME-WAIT狀態的連線; net.core.somaxconn=262114 :選項預設值是128,這個引數用於調節系統同時發起的TCP連線數,在高併發的請求中,預設的值可能會導致連結超時或者重傳,因此需要結合高併發請求數來調節此值; net.core.netdev_max_backlog=262114:該選項表示每個網路介面接收資料包的速率比核心處理這些包的速率快時,允許傳送到佇列資料包的最大數目; net.ipv4.tcp_max_syn_backlog =262114:這個引數表示TCP三次握手建立階段接受SYN請求佇列的最大長度,預設為1024,將其設定得大一些可以使出現Nginx繁忙來不及accept新連線的情況時,Linux不至於丟失客戶端發起的連線請求; net.ipv4.tcp_max_orphans=262114:選項用於設定系統中最多有多少個TCP套接字不被關聯到任何一個使用者檔案控制代碼上。如果超過這個數字,孤立連結將立即被複位並輸出警告資訊。這個限制指示為了防止簡單的DOS攻擊,不用過分依靠這個限制甚至認為的減小這個值,更多的情況是增加這個值; net.ipv4.tcp_synack_retries=1:核心放棄連線之前傳送SYN+ACK包的數量; net.ipv4.tcp_syn_retries=1:核心放棄連線之前傳送SYN包的數量; net.ipv4.tcp_keepalive_time = 600:這個引數表示當keepalive啟用時,TCP傳送keepalive訊息的頻度。預設是2小時,若將其設定的小一些,可以更快地清理無效的連線; net.ipv4.tcp_fin_timeout = 30:這個引數表示當伺服器主動關閉連線時,socket保持在FIN-WAIT-2狀態的最大時間; net.ipv4.ip_local_port_range = 1024 61000:這個引數定義了在UDP和TCP連線中本地(不包括連線的遠端)埠的取值範圍; net.ipv4.tcp_rmem = 10240 87380 12582912:這個引數定義了TCP接受快取(用於TCP接受滑動視窗)的最小值、預設值、最大值; net.ipv4.tcp_wmem = 10240 87380 12582912:這個引數定義了TCP傳送快取(用於TCP傳送滑動視窗)的最小值、預設值、最大值; net.core.netdev_max_backlog = 8096:當網絡卡接受資料包的速度大於核心處理的速度時,會有一個佇列儲存這些資料包。這個引數表示該佇列的最大值; net.core.rmem_default = 6291456:這個引數表示核心套接字接受快取區預設的大小; net.core.wmem_default = 6291456:這個引數表示核心套接字傳送快取區預設的大小; net.core.rmem_max = 12582912:這個引數表示核心套接字接受快取區的最大大小; net.core.wmem_max = 12582912:這個引數表示核心套接字傳送快取區的最大大小; net.ipv4.tcp_syncookies = 1:該引數與效能無關,用於解決TCP的SYN攻擊;

注意:滑動視窗的大小與套接字快取區會在一定程度上影響併發連線的數目。每個TCP連線都會為維護TCP滑動視窗而消耗記憶體,這個視窗會根據伺服器的處理速度收縮或擴張。 引數net.core.wmem_max = 12582912的設定,需要平衡實體記憶體的總大小、Nginx併發處理的最大連線數量而確定。當然,如果僅僅為了提供併發量使伺服器不出現Out Of Memory問題而去降低滑動視窗大小,那麼並不合適,因為滑動窗過小會影響大資料量的傳輸速度。net.core.rmem_default = 6291456、net.core.wmem_default = 6291456、 net.core.rmem_max = 12582912和net.core.wmem_max = 12582912這4個引數的設定需要根據我們的業務特性以及實際的硬體成本來綜合考慮。 Nginx併發處理的最大連線量:由nginx.conf中的work_processes和work_connections引數決定。