實戰 nginx 調優

workey發表於2020-11-16

隱藏 Nginx 版本號

修改 nginx 原始碼

[root@centos60 ~]# wget http://nginx.org/download/nginx-1.14.1.tar.gz

[root@centos60 ~]# tar xzvf nginx-1.14.1.tar.gz -C /usr/local/src/

[root@centos60 ~]# cd /usr/local/src/nginx-1.14.1/

隱藏 Nginx 版本號,需要一共修改 3 個原始碼檔案

1、修改 nginx 軟體版本號

[root@centos60 nginx-1.14.1]# vim src/core/nginx.h

 12 #define nginx_version      1014001
 13 #define NGINX_VERSION      "8.8.8"
 14 #define NGINX_VER          "XWX/" NGINX_VERSION

2、修改 HTTP 頭資訊中的 connection 欄位,防止回顯具體版本號

[root@centos60 nginx-1.14.1]# vim src/http/ngx_http_header_filter_module.c

 49 static u_char ngx_http_server_string[] = "Server: XWX" CRLF;

3、修改 ngx_http_special_response.c 檔案定義了 Nginx 報 404 錯誤時,不回顯版本號。

[root@centos60 nginx-1.14.1]# vim src/http/ngx_http_special_response.c

 35 static u_char ngx_http_error_tail[] =
 36 "<hr><center>XWX</center>" CRLF

編譯和安裝 nginx

1、安裝 nginx 時必須先安裝相應的編譯工具

[root@centos60 nginx-1.14.1]# yum -y install gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre pcre-devel

gcc c  語言編譯器。
gcc-c++ c++ 語言編譯器。
autoconf automake 用於 configure 和 make 編譯的工具。
zlib :nginx 提供 gzip 模組,需要 zlib 庫支援。
openssl :nginx 提供 ssl 功能。
pcre :支援地址重寫 rewrite 功能。

2、建立一個 nginx 使用者用於後期啟動 nginx 程式使用,比你直接使用 root 使用者啟動 nginx 更安全

[root@centos60 nginx-1.14.1]# useradd -s /sbin/nologin -M nginx

-s #指定登入 shell。
-M #不建立家目錄。

3、編譯和安裝 nginx

[root@centos60 nginx-1.14.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-pcre && make -j 4 && make install

--prefix=/usr/local/nginx 挃定安裝路徑
--user=nginx --group=nginx 挃定執行 nginx 迚程的使用者和組
--with-http_ssl_module 支援 ssl 加密
--with-http_realip_module 此模組支援顯示真實來源 IP 地址,當 NGINX 做負載均衡伺服器時,需要這個功能,這樣能夠使得後臺伺服器記錄原始客戶端的 IP 地址。
--with-http_gzip_static_module 開啟nginx支援gunzip壓縮靜態檔案功能,靜態檔案壓縮後,可以節約頻寬
--with-http_dav_module #啟用支援 WebDAV 功能。WebDAV 一種基亍 HTTP 1.1協議的通訊協議。它擴充套件了 HTTP 1.1,在 GET、POST、HEAD 等幾個 HTTP 標準方法以外新增了一些新的方法,使應用程式可直接對 Web Server 直接讀寫,並支援寫檔案鎖定(Locking)及解鎖(Unlock),還可以支援檔案的版本控制。
--with-http_stub_status_module #啟用支援 nginx 監控模組,後期通過呼叫此模組可以監控nginx 狀態。zabbix 也可以通過此模組,來監控 nginx 的效能狀態
--with-http_addition_module #啟用支援(開啟此模組後,nginx 可以在響應 http 請求之前或者之後追加文字內容,比如想在站點底部追加一個 js 戒者 css,可以使用這個模組來實現。)。
--with-http_sub_module #啟用支援(此模組為 nginx 替換響應內容的模組,比如當站點出現什麼敏感字,需要批量修改所有 web 頁面,且想修改很耗時間,可以使用這個模組近行替換。或者想臨時在站點中加上一個通用 js 或者 css 之類的檔案,也可以使用這個模組。)
--with-http_flv_module #啟用支援(支援 HTTP-FLV 方式直播視訊)。
--with-http_mp4_module #啟用支援(此模組允許 nginx 為 H.264/AAC 編譯碼的視訊檔案,如: .mp4、.m4v、和.m4a 副檔名的檔案, 提供偽流媒體服務端支援。偽流媒體是不 Flash 播放器一起配合使用的。 播放器向服務端傳送 HTTP 請求,請求中的查詢串是
以開始時間為引數的,而服務端以流響應,這樣流的開始 位置就能亍請求中的時間相對應。)
--with-pcre #啟用 perl 正規表示式,perl 的正規表示式一般使用在 location 指令和ngx_http_rewrite_module url 重定向模組中。預設 ngx_http_rewrite_module 是就啟用的。

4、啟動 nginx 服務

[root@centos60 nginx-1.14.1]# /usr/local/nginx/sbin/nginx

[root@centos60 nginx-1.14.1]# iptables -F

測試 1:檢視在 http 協議中是否隱藏了版本和軟體名。

測試 2:當訪問時,出現 404 及其它錯誤時也會返回已經隱藏的版本資訊

 

修改 nginx 執行使用者-設定 nginx 的 cpu 親和力

修改 Nginx 執行使用者

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

[root@centos60 ~]# /usr/local/nginx/sbin/nginx -s reload  #動態載入配置檔案

設定 Nginx 執行程式個數

1、Nginx 執行程式個數一般設定為 CPU 的核心數或者核心數 2 倍

[root@centos60 ~]# top  

輸入數字1,檢視有4核心cpu

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

[root@centos60 ~]# yum search pstree

[root@centos60 ~]# yum -y install psmisc

檢視 nginx 管理程式和 4 個 work 程式的父子關係:

設定 Nginx 執行 CPU 的親和力

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

比如伺服器是 8 核 8 執行緒的 cpu,應該配置為如下:

worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

測試 cpu 親和力:
沒有配置 cpu 親和力,檢視

可以看到 nginx master 程式和 worker 程式是父子關係。

[root@centos60 ~]# taskset -cp 28491
pid 28491's current affinity list: 0-3        #發現 0-3,說明 nginx PID 28491,可以在 4 個 cpu上執行

配置 cpu 親和力,檢視:

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

[root@centos60 ~]# /usr/local/nginx/sbin/nginx -s reload

[root@centos60 ~]# taskset -cp 28535
pid 28535's current affinity list: 0 #表示 nginx PID 28535,只能在第一個 cpu 執行

[root@centos60 ~]# taskset -cp 28538
pid 28538's current affinity list: 3  #表示 nginx PID 28538,只能在第四個 cpu 執行

設定 Nginx 每個程式最多可以開啟的檔案數和事件處理模型

Nginx 最多可以開啟檔案數

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

這個指令是指當一個 Nginx 程式開啟的最多檔案描述符數目,理論值應該是最多開啟檔案數(ulimit -n)與 nginx 程式數相除,即:(ulimit -n)/ worker_processes ,但是 nginx 分配請求並不是那麼均勻,所以最好與 ulimit -n 的值保持一致。修改 ulimit -n 的值,可以參考 linux 系統調優的內容。

程式最大可開啟檔案數受限於作業系統,可通過 ulimit -n 命令查詢,以前是 1024,現在是 65535,
修改系統最大檔案開啟數
臨時配置
[root@centos60 ~]# ulimit -SHn 65535
永久配置
[root@centos60 ~]# echo "ulimit -SHn 65535" >> /etc/profile

Nginx 事件處理模型

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

使用epoll模式

Nginx 事件處理模型對比

select,poll,epoll 都是 nginx 下的 IO 多路複用的機制。I/O 多路複用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。Epoll 在 Linux2.6 核心中正式引入,和 select 和 poll 相似,其實都是 I/O 多路複用技術。

epoll 優勢:
1、Epoll 沒有最大併發連線的限制,上限是最大可以開啟檔案的數目,這個數字一般遠大於 2048, 一般來說這個數目和系統記憶體關係很大,具體數目可以 cat /proc/sys/fs/file-max 察看。

2、 效率提升,Epoll 最大的優點就在於它只管你“活躍”的連線,而跟連線總數無關,因此在實際的網路環境中,Epoll 的效率就會遠遠高於 select 和 poll。
3、 Epoll 在這點上使用了“共享記憶體”,更省記憶體,效率更高。

單個程式允許客戶端最大併發連線數

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

worker_connections:這個屬性是指單個工作程式可以允許同時建立外部連線的數量。無論這個連線是外部主動建立的,還是內部建立的。一個工作程式建立一個連線後,程式將開啟一個檔案副本。所以這個數量還受限於,作業系統 ulimit -n 設定的值和 nginx 的 worker_connections 的值。一般情況下系統 ulimit -n、worker_rlimit_nofile 、worker_connections 三者的值是一樣的。nginx 伺服器實際最大併發值就是:worker_processes*worker_connections 的乘積。

每個工作程式程可以處理併發的最大連線數。受限於記憶體和 linux 系統中程式程最大可開啟檔案數。最大併發連線數=65535 * 4 (程式數)= 262,140

[root@centos60 ~]# top -u nginx

Nginx 每個程式使用的記憶體大小,剛啟動的 nginx 程式佔用記憶體也就 1.9M 左右
執行 top 命令後,按下字母 e,可以切換顯示記憶體的單位為: KB、MB、GB、TB、PB

ServerName 和 location 匹配及高效傳輸模式

ServerName 匹配
server_name 指令可以設定基於域名的虛擬主機,根據請求頭部的內容,一個 ip 的伺服器可以配置多個域名。

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

ServerName 配置虛擬主機

在 centos.cn 主機名配置的前面再建立一個 centos.com 的 server 配置。新增在 http 欄位中即可。可以直接新增在 centos.cn 的 server 欄位上方。

注:root html/centos.com/;表示 centos.com 站點的網站根目錄。
[root@centos60 ~]# mkdir /usr/local/nginx/html/centos.com
[root@centos60 ~]# echo "centos.com" > /usr/local/nginx/html/centos.com/index.html
[root@centos60 ~]# /usr/local/nginx/sbin/nginx
[root@centos60 ~]# /usr/local/nginx/sbin/nginx -s reload
[root@centos60 ~]# curl centos.com
centos.com

ServerName 匹配方式
(1)、精確匹配:www.aa.com
(2)、左側萬用字元匹配:*.aa.com
(3)、右側萬用字元匹配:www.*
(4)、正規表示式:~ ^.*\.aa\.com$
(5)、default_server
(5)、服務 IP 地址

[root@centos60 ~]# /usr/local/nginx/sbin/nginx -t       #檢測 nginx 配置檔案是否正確。
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@centos60 ~]# /usr/local/nginx/sbin/nginx -s reload


location 匹配方式,如下:
= 嚴栺匹配。如果這個查詢匹配,那麼將停止搜尋並立即處理此請求
!~為區分大小寫不匹配
!~* 為不區分大小寫不匹配
^~  URL前半部分匹配,不檢查正則。(如果把這個字首用於一個常規字串,那麼告訴 nginx 如果路徑匹配,則不測試剩下的正規表示式。通常用於,以什麼字串開頭的查詢。)
~ 正則匹配,區分大小寫。
~* 正則匹配,不區分大小寫。
\ 轉義。
* 配置任意個任意字元。
$ 以什麼結尾。

location = / {
index index.html index.htm;
#嚴格匹配。 只匹配 / 查詢,即訪問根目錄/, 比如 http://www.centos.cn/ 將匹配此規則
#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理。
#這裡是直接轉發給後端應用伺服器了,也可以是一個靜態首頁
# 這個規則最常使用的規則
}

1. 匹配根目錄
location / {
root html/centos.com/;
index index.html index.htm;
}

注:匹配/目錄,設定 index 主頁為 index.html index.htm;

2. 路徑匹配

[root@centos60 ~]# cd /usr/local/nginx/html/centos.com/
[root@centos60 centos.com]# mkdir static
[root@centos60 centos.com]# echo static > static/1.txt
[root@centos60 centos.com]# curl centos.com/static/1.txt
static


3. 資原始檔匹配

 

 

        location ~* \.jpg$ {
            deny all;
        }

        location ~* \.(gif|jpg|png|js|css)$ {
                deny all;
        }
# 匹配任何以 gif、jpg 、png 、js、css 結尾的請求。

 

匹配出以.php 結尾的檔案且配置時不區分大小寫

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

 url 中以.php 結尾的檔案且區分大小寫,都按{   }中的方法進行處理 。

匹配出以.txt 結尾的檔案且不區分大小寫

location ~* \.txt {
root file;
}

開啟高效傳輸模式

[root@centos60 ~]# vim /usr/local/nginx/conf/nginx.conf

Include mime.types;  #媒體型別。
default_type application/octet-stream;  預設媒體型別 足夠。
sendfile on; 開啟高效檔案傳輸模式,sendfile指令指定nginx是否呼叫sendfile函式來輸出檔案,對於普通應用設為 on,如果用來進行下載等應用磁碟 IO 重負載應用,可設定為 off,以平衡磁碟與網路 I/O 處理速度,降低系統的負載。注意:如果圖片顯示不正常把這個改成 off。
tcp_nopush on;  必須在 sendfile 開啟模式才有效,防止網路阻塞,積極的減少網路報文段的數量。

連線超時時間

主要目的是保護伺服器資源,CPU,記憶體,控制連線數,因為建立連線也是需要消耗資源的,TCP 的三次握手四次揮手等,我們一般斷掉的是那些建立連線但是不做事兒,也就是我建立了連結開始,但是後續的握手過程沒有進行,那麼我們的連結處於等待狀態的,全部斷掉!同時我們也希望 php 建議短連結,消耗資源少。

keepalived_timeout 客戶端連線保持會話超時時間,超過這個時間,伺服器斷開這個連結。
tcp_nodelay;也是防止網路阻塞,不過要包含在 keepalived 引數才有效。
client_header_timeout 客戶端請求頭讀取超時時間,如果超過這個時間沒有傳送任何資料,nginx將返回 request time out 的錯誤。
client_body_timeout 客戶端請求主體超時時間,超過這個時間沒有傳送任何資料,和上面一樣的錯誤提示。
send_timeout 響應客戶端超時時間,這個超時時間僅限於兩個活動之間的時間,如果超過這個時間,客戶端沒有任何活動,nginx 關閉連線。

檔案上傳大小限制
我們知道 PHP 可以修改上傳檔案大小限制,nginx 也可以修改。
http {
……
client_max_body_size 10m;

Fastcgi 調優-gzip 壓縮網頁調優-expires 快取調優

Fastcgi 相關概念

FastCGI 是一種協議,規定了 FastCGI 應用和支援 FastCGI 的 Web 伺服器之間的介面。Fastcgi 是靜態服務和動態服務的一個介面 FastCGI 是二進位制連續傳遞的。

Fastcgi 相關的個概念如下:
Cache:寫入快取區
Buffer:讀取快取區
Fastcgi 是靜態服務和動態服務的一個介面

fastcgi_connect_timeout 300; #指定連結到後端 FastCGI 的超時時間。
fastcgi_send_timeout 300; #向 FastCGI 傳送請求的超時時間,這個值是指已經完成兩次握手後向 FastCGI 傳送請求的超時時間。
fastcgi_read_timeout 300; #指定接收 FastCGI 應答的超時時間,這個值是指已經完成兩次握手後接收 FastCGI 應答的超時時間。
fastcgi_buffer_size 64k; #指定讀取 FastCGI 應答第一部分需要用多大的緩衝區,這個值表示將使用 1 個 64KB 的緩衝區讀取應答的第一部分(應答頭),可以設定為 gastcgi_buffers 選項指定的緩衝區大小。
fastcgi_buffers 4 64k; #指定本地需要用多少和多大的緩衝區來緩衝 FastCGI 的應答請求,如果一個 php 指令碼所產生的頁面大小為 256KB,那麼會分配 4 個 64KB 的緩衝區來快取,如果頁面大小大於256KB,那麼大於 256KB 的部分會快取到 fastcgi_temp 指定的路徑中,但是這並不是好方法,因為記憶體中的資料處理速度要快於磁碟。一般這個值應該為站點中 php 指令碼所產生的頁面大小的中間值,如果站點大部分指令碼所產生的頁面大小為 256KB,那麼可以把這個值設定為“8 16K”、“4 64k”等。
fastcgi_busy_buffers_size 128k; #建議設定為 fastcgi_buffer 的兩倍,繁忙時候的 buffer。
fastcgi_temp_file_write_size 128k; #表示在寫入快取檔案時使用多大的資料塊,預設值是fastcgi_buffers的兩倍。設定上述數值設定小時若負載上來時可能報 502Bad Gateway。

日誌切割優化-目錄檔案訪問控制-來源訪問控制

 

禁止使用 IP 訪問網站和 301 優化-防盜鏈-錯誤頁面的提示-開啟認證功能

 

 

相關文章