Nginx介紹
nginx是一款來自俄羅斯開發人員開源的高性能的HTTP服務器和方向代理服務器,因為它的性能非常優秀,而且是免費,所以,在國內被廣泛運用于web服務器、負載均衡服務器、郵件代理服務器。
它的性能非常優秀,是建立在非常強大的服務配置上,同時,性能優秀也不代表就不會有性能問題,作為性能測試人員,這款軟件是必須要掌握的。
Nginx安裝
nginx的安裝方法很多,也可以支持不同的操作系統,但是,作為性能測試人員學習nginx,我還是建議選擇一臺centos7系統,然后,采用源碼編譯方式安裝,因為,用這種方式,可以方便安裝拓展插件。在性能測試中,經常需要使用性能監控,源碼編譯方式安裝的nginx,可以用第三方監控插件來監控它。
- 首先,安裝依賴
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參數,就是nginx的安裝路徑,所以,它的配置文件路徑在
/usr/local/nginx/config/nginx.conf。
#定義nginx運行的用戶和用戶組
#user nobody;
# 啟動的進程數,一般依據CPU核數來定
worker_processes 2;
#nginx 默認沒有開啟利用多核 CPU, 通過增加 worker_cpu_affinity 配置參數來充分利用多核 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 以上版本內核中的高性能網絡 I/O 模型,如果跑在 FreeBSD 上面,就用 kqueue 模型。
#epoll 是多路復用 IO(I/O Multiplexing) 中的一種方式,
#但是僅用于 linux2.6 以上內核,可以大大提高 nginx 的性能
use epoll;
#單個worker的最大并發鏈接數
#最大客戶連接數由 worker_processes 和 worker_connections 決定
#即 max_client=worker_processes*worker_connections,
#在作為反向代理時:max_client=worker_processes*worker_connections / 4
worker_connections 1024;
#一個 nginx 進程打開的最多文件描述符數目,理論值應該是最多打開文件數
#(系統的值 ulimit -n)與 nginx 進程數相除,但是 nginx 分配請求并不均勻,
#所以建議與 ulimit -n 的值保持一致。
#worker_rlimit_nofile 1024;
}
#設置http服務器
http {
#文件擴展名與文件類型映射表
include mime.types;
#默認文件類型
default_type Application/octet-stream;
#設置日志
#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;
#服務器名字的 hash 表大小
server_names_hash_bucket_size 128;
#上傳文件大小限制
client_header_buffer_size 32k;
#設定請求緩存
large_client_header_buffers 4 64k;
client_max_body_size 8m;
#sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,
#對于普通應用,必須設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設置為 off,
#以平衡磁盤與網絡I/O處理速度,降低系統的uptime.
sendfile on;
#開啟目錄列表訪問,合適下載服務器,默認關閉。
#autoindex off;
#防止網絡阻塞
#tcp_nopush on;
#tcp_nodelay on;
#客戶端連接超時時長
#keepalive_timeout 0;
keepalive_timeout 65;
#客戶端請求頭超時時長
#client_header_timeout 10;
#客戶端請求體超時時長
#client_body_timeout 10;
#告訴 nginx 關閉不響應的客戶端連接,釋放客戶端所占有的內存空間
#reset_timedout_connection on;
#客戶端響應超時時長,如果在這段時間內,客戶端沒有讀取任何數據,nginx 就會關閉連接
#send_timeout 10;
########################################################
#FastCGI 相關參數是為了改善網站的性能:減少資源占用,提高訪問速度。
#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壓縮開關
#gzip on;
#最小壓縮文件大小
#gzip_min_length 1k;
#壓縮緩沖區
#gzip_buffers 4 16k;
#壓縮版本(默認 1.1,前端如果是 squid2.5 請使用 1.0)
#gzip_http_version 1.0;
#壓縮等級,gzip 壓縮比,1 為最小,處理最快;9 為壓縮比最大,處理最慢,傳輸速度最快,也最消耗 CPU;
#gzip_comp_level 2;
#壓縮類型,默認就已經包含 text/html,所以下面就不用再寫了,寫上去也不會有問題,但是會有一個 warn。
#gzip_types text/plain application/x-JAVAscript text/css application/xml;
#gzip_vary on;
########################################################
#開啟IP連接數限制的時候使用
#limit_zone crawler $binary_remote_addr 10m;
#負載均衡
#upstream up_app {
# server 192.168.x.x:port;
# server 192.168.x.x:port;
#}
#server服務
server {
#監聽端口,http協議默認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;
}
#圖片緩存時間設置
#location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
# expires 10d;
#}
#JS 和 CSS 緩存時間設置
#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配置參數
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
#數字簽名,此處使用MD5
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
Nginx優化
從上面可以看到nginx的配置參數非常多,看得人頭皮發麻,那要怎么才能做好nginx的性能優化呢?nginx是一個軟件,這個軟件安裝在操作系統中,所以,nginx的性能受nginx的配置參數和操作系統參數限制,我們只需要做好這兩方面的優化,nginx的性能就能得到提升。

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