Nginx介紹
nginx是一款來自俄羅斯開發(fā)人員開源的高性能的HTTP服務(wù)器和方向代理服務(wù)器,因為它的性能非常優(yōu)秀,而且是免費,所以,在國內(nèi)被廣泛運用于web服務(wù)器、負載均衡服務(wù)器、郵件代理服務(wù)器。
它的性能非常優(yōu)秀,是建立在非常強大的服務(wù)配置上,同時,性能優(yōu)秀也不代表就不會有性能問題,作為性能測試人員,這款軟件是必須要掌握的。
Nginx安裝
nginx的安裝方法很多,也可以支持不同的操作系統(tǒng),但是,作為性能測試人員學(xué)習(xí)nginx,我還是建議選擇一臺centos7系統(tǒng),然后,采用源碼編譯方式安裝,因為,用這種方式,可以方便安裝拓展插件。在性能測試中,經(jīng)常需要使用性能監(jiān)控,源碼編譯方式安裝的nginx,可以用第三方監(jiān)控插件來監(jiān)控它。
- 首先,安裝依賴
yum install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel -y
- 然后,安裝pcre軟件
訪問pcre軟件下載頁面,選擇一個版本下載
cd /opt
wget https://sourceforge.NET/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz && tar -xzvf pcre-8.45.tar.gz
cd pcre-8.45
./configure
make && make install
- 再,安裝nginx
訪問nginx的下載頁面,選擇一個版本下載
cd /opt
wget http://nginx.org/download/nginx-1.24.0.tar.gz && tar -xzvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/opt/pcre-8.45
make && make install
啟動nginx:
/usr/local/nginx/sbin/nginx
配置文件:
/usr/local/nginx/conf/nginx.conf
檢查nginx配置文件:
/usr/local/nginx/sbin/nginx -t
重新加載配置文件:
/usr/local/nginx/sbin/nginx -s reload
停止nginx:
/usr/local/nginx/sbin/nginx -s stop
Nginx配置
用源碼編譯安裝,要看你把nginx安裝在哪個路徑,配置文件nginx.conf會在安裝路徑中,如上面的安裝時指定了prefix參數(shù),就是nginx的安裝路徑,所以,它的配置文件路徑在
/usr/local/nginx/config/nginx.conf。
#定義nginx運行的用戶和用戶組
#user nobody;
# 啟動的進程數(shù),一般依據(jù)CPU核數(shù)來定
worker_processes 2;
#nginx 默認沒有開啟利用多核 CPU, 通過增加 worker_cpu_affinity 配置參數(shù)來充分利用多核 CPU
#worker_cpu_affinity 00000001 00000010;
#全局錯誤日志配置
#error_log logs/error.log;
#錯誤日志級別[debug | info | notice | warn | errot | crit]
#error_log logs/error.log notice;
#error_log logs/error.log info;
#PID文件路徑,記錄nginx的進程ID
#pid logs/nginx.pid;
#工作模式
events {
#參考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
#epoll 模型是 linux 2.6 以上版本內(nèi)核中的高性能網(wǎng)絡(luò) I/O 模型,如果跑在 FreeBSD 上面,就用 kqueue 模型。
#epoll 是多路復(fù)用 IO(I/O Multiplexing) 中的一種方式,
#但是僅用于 linux2.6 以上內(nèi)核,可以大大提高 nginx 的性能
use epoll;
#單個worker的最大并發(fā)鏈接數(shù)
#最大客戶連接數(shù)由 worker_processes 和 worker_connections 決定
#即 max_client=worker_processes*worker_connections,
#在作為反向代理時:max_client=worker_processes*worker_connections / 4
worker_connections 1024;
#一個 nginx 進程打開的最多文件描述符數(shù)目,理論值應(yīng)該是最多打開文件數(shù)
#(系統(tǒng)的值 ulimit -n)與 nginx 進程數(shù)相除,但是 nginx 分配請求并不均勻,
#所以建議與 ulimit -n 的值保持一致。
#worker_rlimit_nofile 1024;
}
#設(shè)置http服務(wù)器
http {
#文件擴展名與文件類型映射表
include mime.types;
#默認文件類型
default_type Application/octet-stream;
#設(shè)置日志
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
#服務(wù)器名字的 hash 表大小
server_names_hash_bucket_size 128;
#上傳文件大小限制
client_header_buffer_size 32k;
#設(shè)定請求緩存
large_client_header_buffers 4 64k;
client_max_body_size 8m;
#sendfile 指令指定 nginx 是否調(diào)用 sendfile 函數(shù)(zero copy 方式)來輸出文件,
#對于普通應(yīng)用,必須設(shè)為 on,如果用來進行下載等應(yīng)用磁盤IO重負載應(yīng)用,可設(shè)置為 off,
#以平衡磁盤與網(wǎng)絡(luò)I/O處理速度,降低系統(tǒng)的uptime.
sendfile on;
#開啟目錄列表訪問,合適下載服務(wù)器,默認關(guān)閉。
#autoindex off;
#防止網(wǎng)絡(luò)阻塞
#tcp_nopush on;
#tcp_nodelay on;
#客戶端連接超時時長
#keepalive_timeout 0;
keepalive_timeout 65;
#客戶端請求頭超時時長
#client_header_timeout 10;
#客戶端請求體超時時長
#client_body_timeout 10;
#告訴 nginx 關(guān)閉不響應(yīng)的客戶端連接,釋放客戶端所占有的內(nèi)存空間
#reset_timedout_connection on;
#客戶端響應(yīng)超時時長,如果在這段時間內(nèi),客戶端沒有讀取任何數(shù)據(jù),nginx 就會關(guān)閉連接
#send_timeout 10;
########################################################
#FastCGI 相關(guān)參數(shù)是為了改善網(wǎng)站的性能:減少資源占用,提高訪問速度。
#fastcgi_connect_timeout 300;
#fastcgi_send_timeout 300;
#fastcgi_read_timeout 300;
#fastcgi_buffer_size 64k;
#fastcgi_buffers 4 64k;
#fastcgi_busy_buffers_size 128k;
#fastcgi_temp_file_write_size 128k;
########################################################
#gzip壓縮開關(guān)
#gzip on;
#最小壓縮文件大小
#gzip_min_length 1k;
#壓縮緩沖區(qū)
#gzip_buffers 4 16k;
#壓縮版本(默認 1.1,前端如果是 squid2.5 請使用 1.0)
#gzip_http_version 1.0;
#壓縮等級,gzip 壓縮比,1 為最小,處理最快;9 為壓縮比最大,處理最慢,傳輸速度最快,也最消耗 CPU;
#gzip_comp_level 2;
#壓縮類型,默認就已經(jīng)包含 text/html,所以下面就不用再寫了,寫上去也不會有問題,但是會有一個 warn。
#gzip_types text/plain application/x-JAVAscript text/css application/xml;
#gzip_vary on;
########################################################
#開啟IP連接數(shù)限制的時候使用
#limit_zone crawler $binary_remote_addr 10m;
#負載均衡
#upstream up_app {
# server 192.168.x.x:port;
# server 192.168.x.x:port;
#}
#server服務(wù)
server {
#監(jiān)聽端口,http協(xié)議默認80端口
listen 80;
#定義使用的域名,多個用空格隔開
server_name localhost;
#編碼格式
#charset utf-8;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#圖片緩存時間設(shè)置
#location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
# expires 10d;
#}
#JS 和 CSS 緩存時間設(shè)置
#location ~ .*.(js|css)?$ {
# expires 1h;
#}
# proxy the php scripts to Apache listening on 127.0.0.1:80
#
#location ~ .php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ .php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
#ssl證書文件位置
# ssl_certificate cert.pem;
#ssl證書key位置
# ssl_certificate_key cert.key;
#ssl配置參數(shù)
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
#數(shù)字簽名,此處使用MD5
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
Nginx優(yōu)化
從上面可以看到nginx的配置參數(shù)非常多,看得人頭皮發(fā)麻,那要怎么才能做好nginx的性能優(yōu)化呢?nginx是一個軟件,這個軟件安裝在操作系統(tǒng)中,所以,nginx的性能受nginx的配置參數(shù)和操作系統(tǒng)參數(shù)限制,我們只需要做好這兩方面的優(yōu)化,nginx的性能就能得到提升。

nginx配置參數(shù)優(yōu)化
- 工作進程與最大連接數(shù)
nginx支持的并發(fā)連接數(shù)越大,理論上能支持的并發(fā)用戶數(shù)就越多,所以,從性能角度來說,期望這個越大越好。而這個值等于worker_processes與work_connections的乘積。worker_processes要看cpu的核數(shù),如果設(shè)置固定數(shù)值,就要小于等于CPU核數(shù),如果設(shè)置為auto,啟動nginx時,會根據(jù)CPU的繁忙情況,自動參數(shù)worker數(shù)量。
work_connections是單個worker的最大連接數(shù),這個值受系統(tǒng)ulimit的限制,ulimit -n可以看到系統(tǒng)一個進程允許打開的最大文件數(shù)量,同時系統(tǒng)還有/proc/sys/fs/file-max限制整個系統(tǒng)允許打開的最大文件數(shù),即worker_processes與work_connections的乘積最大不能超過file-max的限制,所以,還要適當(dāng)調(diào)整系統(tǒng)參數(shù)限制。
- 使用HTTP/2
HTTP/2使應(yīng)用程序更快,更簡單且更可靠。 HTTP/2的主要目標(biāo)是通過啟用完整的請求和響應(yīng)多路復(fù)用來減少延遲,通過有效壓縮 HTTP 標(biāo)頭字段來最小化協(xié)議開銷,并增加對請求優(yōu)先級和服務(wù)器推送的支持。
- 維護SSL會話
客戶端每次發(fā)出請求時都進行新的 SSL 握手,默認情況下,內(nèi)置會話緩存并不是最佳選擇,因為它只能由一個工作進程使用,并且可能導(dǎo)致內(nèi)存碎片,最好使用共享緩存。使用 ssl_session_cache 時,通過 SSL 保持連接的性能可以大大提高。
- 盡可能在server_name指令中使用確切的名稱
確切名稱,以星號開頭的通配符名稱和以星號結(jié)尾的通配符名稱存儲在綁定到偵聽端口的三個哈希表中。首先搜索確切名稱哈希表。 如果未找到名稱,則搜索具有以星號開頭的通配符名稱的哈希表。 如果未在此處找到名稱,則搜索帶有通配符名稱以星號結(jié)尾的哈希表。 搜索通配符名稱哈希表比搜索精確名稱哈希表要慢,因為名稱是按域部分搜索的。
- 使用$request_uri來避免使用正則表達式
使用內(nèi)置變量$request_uri,我們可以完全避免進行任何捕獲或匹配。默認情況下,正則表達式的代價較高,并且會降低性能。
- 使用return代替rewrite做重定向
return 語句比通過位置塊評估 RegEx 更簡單,更快捷
nginx機器系統(tǒng)參數(shù)優(yōu)化
- 系統(tǒng)最大線程數(shù)
修改/etc/security/limits.conf,在這個文件中,添加如下配置:
* soft nofile 1000000
* hard nofile 1000000
* soft nproc 655360
* hard nproc 655360
- 內(nèi)存參數(shù)配置
我們可以使用sysctl -w 修改如下參數(shù):
# 系統(tǒng)最大可以打開的句柄數(shù)
fs.file-max=2024000
#TIME_WAIT狀態(tài)的socket,重新用于TCP連接
net.ipv4.tcp_tw_reuse=1
#調(diào)整keepalive的頻率
net.ipv4.tcp_keepalive_time=60
#FIN_WAIT狀態(tài)的socket,最大時長
net.ipv4.tcp_fin_timeout=30
#運行TIME_WAIT套接字的最大數(shù)量
net.ipv4.tcp_max_tw_buckets=5000
#端口范圍
net.ipv4.ip_local_port_range=1024 65535
###########下面四個根據(jù)業(yè)務(wù)邏輯與硬件情況靈活調(diào)整
#內(nèi)核套接字接受緩存區(qū)默認大小
net.core.rmem_default=6291456
#內(nèi)核套接字發(fā)送緩存區(qū)默認大小
net.core.wmem_default=6291456
#內(nèi)核套接字接受緩存區(qū)最大大小
net.core.rmem_max=12582912
#內(nèi)核套接字發(fā)送緩存區(qū)最大大小
net.core.wmem_max=12582912
#定義了TCP接受緩存的最小值、默認值、最大值
net.ipv4.tcp_rmem = 10240 87380 12582912
#定義TCP發(fā)送緩存的最小值、默認值、最大值
net.ipv4.tcp_wmem = 10240 87380 12582912
#設(shè)置啟用timewait快速回收
net.ipv4.tcp_tw_recycle = 1
#調(diào)節(jié)系統(tǒng)同時發(fā)起的TCP連接數(shù)
net.core.somaxconn=262114
然后再使用sysctl -p生效
做好這些優(yōu)化配置,nginx性能,就能得到極大的提升。