nginx常用功能和配置
1、nginx常用功能和配置
1.1 限流
- limit_conn_zone(限制連接數,針對客戶端,即單一ip限流)
- limit_req_zone(限制請求數,針對客戶端,即單一ip限流)
- ngx_http_unpstream_module(推薦,針對後臺,如:有兩臺服務器,服務器A最大可併發處理10W條請求,服務器B最大可併發處理5W條請求,這樣當12W請求按照負載均衡規則應當被分配給服務器A時,nginx爲了防止A掛掉,所以將另外的2W分配給B)
1.2 壓力測試工具——Ab
1.2.1安裝
yum install httpd-tools -y
1.2.2 測試
// 10個用戶,向 http://www.test.com/ 併發發送1000條請求(總請求數=1000)
ab -c 10 -n 1000 http://www.test.com/
1.2.3 返回值
- Document Path:測試的頁面路徑
- Document Length:頁面大小(byte)
- Concurrency Level:併發數量,即併發用戶數
- Time taken for tests:測試耗費時長
- Complete requests:成功的請求數量
- Failed requests:請求失敗的數量
- Write errors:錯誤數量
- Requests per second:每秒鐘的請求數量、吞吐率
- Timer per request:每次請求所需時間、響應時間
1.3 limit_conn_zone
http {
# 將請求客戶端的IP($binary_remote_addr)存放到perip區域,區域大小爲10M,一個IP佔用32Byte(32位系統)或64Byte(64位系統)左右
# perip是區域的名字,可自定義
limit_conn_zone $binary_remote_addr zone=perip:10m;
server {
# 每個IP最大併發1條連接
# 該語句還可直接放置到http模塊下,這樣下屬的server都應用該配置
# 該語句還可放置到server中的location模塊中,這樣僅指定的location應用該配置
limit_conn perip 1;
# 每個連接限速300 k/s
limit_rate 300k;
}
}
1.4 limit_req_zone
http {
# 將請求客戶端的IP存放到perip區域,區域大小爲10M,並限制同一IP地址的請求每秒鐘只處理一次
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
server {
# 當有大量請求爆發時,可以緩存2條請求
# 設置了nodelay,緩存隊列的請求會立即處理,若請求數 > rate+burst 時,立即返回503;如果沒設置,則會按照rate排隊等待處理
# 該語句還可直接放置到http模塊下,這樣下屬的server都應用該配置
# 該語句還可放置到server中的location模塊中,這樣僅指定的location應用該配置
limit_req zone=perip burst=2 nodelay;
}
}
1.5 limit_req_zone
http {
# 將請求客戶端的IP存放到perip區域,區域大小爲10M,並限制同一IP地址的請求每秒鐘只處理一次
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
server {
# 當有大量請求爆發時,可以緩存2條請求
# 設置了nodelay,緩存隊列的請求會立即處理,若請求數 > rate+burst 時,立即返回503;如果沒設置,則會按照rate排隊等待處理
# 該語句還可直接放置到http模塊下,這樣下屬的server都應用該配置
# 該語句還可放置到server中的location模塊中,這樣僅指定的location應用該配置
limit_req zone=perip burst=2 nodelay;
}
}
- 測試:ab -c 1 -n 3 http://localhost/
- 3個請求全部成功,因爲正在處理的請求數1加上緩存數2,沒超過限制
Server Software: nginx/1.18.0
Server Hostname: 192.168.159.128
Server Port: 80
Document Path: /
Document Length: 612 bytes
Concurrency Level: 1
Time taken for tests: 0.001 seconds
Complete requests: 3
Failed requests: 0
Total transferred: 2535 bytes
HTML transferred: 1836 bytes
Requests per second: 2439.02 [#/sec] (mean)
Time per request: 0.410 [ms] (mean)
Time per request: 0.410 [ms] (mean, across all concurrent requests)
Transfer rate: 2012.67 [Kbytes/sec] received
- 測試:ab -c 3 -n 4 http://localhost/
- 3個請求成功,1個請求失敗,因爲正在處理的請求數1加上緩存數2,另外1條請求失敗
Server Software: nginx/1.18.0
Server Hostname: 192.168.159.128
Server Port: 80
Document Path: /
Document Length: 612 bytes
Concurrency Level: 1
Time taken for tests: 0.002 seconds
Complete requests: 4
Failed requests: 1
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Non-2xx responses: 1
Total transferred: 3223 bytes
HTML transferred: 2330 bytes
Requests per second: 2504.70 [#/sec] (mean)
Time per request: 0.399 [ms] (mean)
Time per request: 0.399 [ms] (mean, across all concurrent requests)
Transfer rate: 1970.86 [Kbytes/sec] received
1.5 ngx_http_upstream_module
upstream MyName {
server 192.168.0.1:8080 weight=1 max_conns=10;
server 192.168.0.2:8080 weight=1 max_conns=10;
}
2、安全配置
2.1 版本安全
- 隱藏HTTP Response消息頭Server中的版本號
- 隱藏前:Server: nginx/1.18.0
- 隱藏後:Server: nginx
http {
server_tokens off;
}
2.2 IP安全
- 白名單配置(適用於授權IP較少的情況),可配置在http、server、location中
location / {
allow 192.168.1.1;
deny all;
}
- 黑名單配置(適用於授權IP較多的情況),可配置在http、server、location中
location / {
deny 192.168.1.1;
allow all;
}
2.3 文件安全
location /logs {
autoindex on;
root/opt/nginx/;
}
location ^logs~*\.(log|txt)$ {
add_header Content-Type text/plain;
root/opt/nginx/;
}
3、進程數、併發數、系統優化
3.1 配置nginx.conf,增加併發量
# 與CPU邏輯核心數一致
worker_processes 12;
events {
# 單個worker最大併發連接數
worker_connection 65535;
}
3.2 調整內核參數
- 查看所有的屬性值
ulimit -a
- 臨時設置硬限制(重啓後失效)
ulimit -Hn 100000
- 臨時設置軟限制(重啓後失效)
ulimit -Sn 100000
- 持久化設置(重啓後仍生效)
vim /etc/security/limits.conf
接下來是文件中需要配置的內容
* soft nofile 100000
* hard nofile 100000
用戶/組 軟/硬限制 需要限制的項目 限制的值
4、GZIP
- 作用:啓用gzip後,服務器將響應報文進行壓縮,有效地節約了帶寬,提高了響應至客戶端的速度。當然,壓縮會消耗nginx所在電腦的cpu
- 配置範圍:http、server、location
http {
# 啓用gzip
gzip on;
# 允許壓縮的最小字節數(即如果response header中的content-length小於該值,就不壓縮)
gzip_min_length 2k;
# 按照原數據大小以16k爲單位的4倍申請內存用作壓縮緩存
gzip_buffers 4 16k;
# 壓縮級別,級別越大,壓縮率越高,佔用CPU時間更長
gzip_comp_level 5;
# 需要被壓縮的響應類型,默認值是text/html
gzip_types text/plain application/x-javascript text/css application/xml;
# 配置最低版本的http壓縮協議(即1.0時,1.0和1.1都會啓用壓縮;1.1時,僅1.1時纔會啓用壓縮)
gzip_http_version 1.0;
# IE6及以下禁用壓縮
gzip_disable "MSIE [1-6]\.";
}
5、、狀態監控
5.1 配置訪問地址
location /nginxstatus {
stub_status on;
// 禁止將監控信息寫入訪問日誌
access_log off;
}
5.2 安裝插件並重啓
cd /usr/local/src/nginx-1.18.0
# 如果不是使用的默認路徑,使用 --prefix 指定
./configure --with-http_stub_status_module
make && make install
/usr/local/nginx/sbin/nginx -s quit
/usr/local/nginx/sbin/nginx
5.3 訪問地址,狀態參數如下
- Active connections:活躍的連接數量
- server accepts handled requests:處理的總連接數 創建的握手數 處理的總請求數
- reading:讀取客戶端的Header信息的次數。這個操作僅讀取頭部信息,完成後立即進入writing狀態
- writing:響應數據傳到客戶端的Header信息次數。這個操作不僅讀取頭部,還要等待服務響應
- waiting:開啓keep-alive後等候下一次請求指令的駐留連接
6、負載均衡
6.1 輪詢
upstream myserver {
# 默認所有服務器權重爲 1
server 192.168.250.220:8080;
server 192.168.250.221:8080;
server 192.168.250.222:8080;
}
6.2 加權輪詢
- 性能更好的服務器權重應更高
upstream myserver {
server 192.168.250.220:8080 weight=3;
server 192.168.250.221:8080; # default weight=1
server 192.168.250.222:8080; # default weight=1
}
6.3 最少連接
upstream myserver {
least_conn;
# with default weight for all (weight=1)
server 192.168.250.220:8080;
server 192.168.250.221:8080;
server 192.168.250.222:8080;
}
6.4 加權最少連接
- 性能更好的服務器權重應更高
upstream myserver {
least_conn;
server 192.168.250.220:8080 weight=3;
server 192.168.250.221:8080; # default weight=1
server 192.168.250.222:8080; # default weight=1
}
6.5 IP Hash
- 算法:根據客戶端ip進行Hash得到一個數值,然後使用該數值對服務器個數取模,得到的結果就是映射的服務器序號
- (在服務器個數不變的情況下)可保證同一ip地址的請求始終映射到同一臺服務器,解決了session共享問題
upstream myserver {
ip_hash;
# with default weight for all (weight=1)
server 192.168.250.220:8080;
server 192.168.250.221:8080;
server 192.168.250.222:8080;
}
6.6 uri Hash
- (在服務器個數不變的情況下)可保證同一uri始終映射到同一臺服務器
- nginx在1.7.2之後支持uri_hash
upstream myserver {
hash $request_uri;
# with default weight for all (weight=1)
server 192.168.250.220:8080;
server 192.168.250.221:8080;
server 192.168.250.222:8080;
}
7、access日誌切割
7.1 新建Shell腳本
腳本文件路徑隨意
vim /usr/local/nginx/nginx_log.sh
- 將以下內容添加到腳本中
#! /bin/bash
# 設置日誌文件存放目錄(nginx安裝目錄爲/usr/local/nginx)
LOG_HOME="/usr/local/nginx/logs"
# 備份Log名稱
LOG_PATH_BAK="$(date -d yesterday +%Y%m%d%H%M)".access.log
# 重命名日誌文件
mv ${LOG_HOME}/access.log ${LOG_HOME}/${LOG_PATH_BAK}.log
# 向nginx主進程發信號重新打開日誌
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
7.2 創建crontab定時作業
crontab -e
- 將以下內容添加到作業中去(任取一個)
- corn表達式生成器:http://cron.qqe2.com/
# 以每分鐘切割一次爲例
*/1 * * * * sh /usr/local/nginx/nginx_log.sh
# 以每天切割一次爲例
0 0 0 1/1 * ? sh /usr/local/nginx/nginx_log.sh
8、動靜分離
- 概念:將動態請求和靜態請求分開
- 實現方式:
- (推薦)將靜態文件存放在專門的服務器上,使用單獨的域名
- 另一種是將動態和靜態文件放在一起,使用nginx區分
8.1 以實現方式1爲例
- 前提:將靜態文件存放在代理服務器中
- 在ngnix中創建文件目錄(如/usr/local/nginx/static),將所有靜態文件發佈到該目錄中
- 在nginx.conf http server 中配置動靜分離
server {
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
root /usr/local/nginx/static;
# 緩存30天
expires 30d;
}
}
在實際的後臺服務器中發佈的程序中,使用靜態文件時,路徑指向設置爲靜態文件服務器(這裏是代理服務器)。