前言:
最近相對比較閒,整理下之前工做中學到的東西,將接觸到生產環境中的內容都深刻學習一下,nginx與tomcat的優化是在山西ott項目上接觸到的,直接操做配置文件很容易,但更多的配置參數與優化方式仍是須要了解的,先得知道問題在哪裏,而後再作。javascript
Nginx調優
目錄php
軟件調優
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. 集羣代理優化
系統內核參數優化css
Nginx軟件調優
1. 隱藏 Nginx 版本號html
爲何要隱藏 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 版本號和軟件名java
爲何要隱藏 Nginx 版本號和軟件名:通常來講,軟件的漏洞都與版本有關,隱藏版本號是爲了防止惡意用戶利用軟件漏洞進行攻擊,而軟件名能夠進行修改,不然黑客知道是 Nginx 服務器更容易進行攻擊,須要注意的是,隱藏 Nginx 軟件名須要從新編譯安裝 Nginx ,若是沒有該方面需求儘可能不要作node
1) 修改:/usr/local/src/nginx-1.6.3/src/core/nginx.hpython
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.cnginx
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.cweb
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
|
參數詳解
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 = 629145六、net.core.wmem_default = 629145六、 net.core.rmem_max = 12582912和net.core.wmem_max = 12582912這4個參數的設置須要根據咱們的業務特性以及實際的硬件成原本綜合考慮。 Nginx併發處理的最大鏈接量:由nginx.conf中的work_processes和work_connections參數決定。