安基網 首頁 系統 Web技術 查看內容

不錯的Nginx配置介紹及性能調優

2019-12-3 11:09| 投稿: xiaotiger |來自: 互聯網


免責聲明:本站系公益性非盈利IT技術普及網,本文由投稿者轉載自互聯網的公開文章,文末均已注明出處,其內容和圖片版權歸原網站或作者所有,文中所述不代表本站觀點,若有無意侵權或轉載不當之處請從網站右下角聯系我們處理,謝謝合作!

摘要: 前言Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,在BSD-like 協議下發行。其特點是占有內存少,并發能力強,事實上nginx的并發能力在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。可以在大多數 UnixLinux ...

前言

Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,在BSD-like 協議下發行。其特點是占有內存少,并發能力強,事實上nginx的并發能力在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。


可以在大多數 UnixLinux OS 上編譯運行,并有 Windows 移植版。是一個很強大的高性能Web和反向代理服務,它具有很多非常優越的特性,在連接高并發的情況下,Nginx是Apache服務不錯的替代品:Nginx在美國是做虛擬主機生意的老板們經常選擇的軟件平臺之一,能夠支持高達 50,000 個并發連接數的響應。

Nginx作為負載均衡服務:Nginx 既可以在內部直接支持 Rails 和 PHP 程序對外進行服務,也可以支持作為 HTTP 代理服務 對外進行服務。Nginx采用C進行編寫,不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多。



一、Nginx配置說明

1、server 代碼塊


server 代碼塊位于 http 代碼塊內部,每一個 server 都可以用來配置一個虛擬主機。也就是說,每一個 server 代表了一個虛擬服務器的配置信息。

可以添加多個 server 來配置多個虛擬主機。

server 中的主要配置有:

  • listen 虛擬主機監聽的端口
  • server_name 虛擬主機的域名或 IP 地址,可以配置多個(用空格隔開)
  • root 虛擬主機的根目錄
  • index 虛擬主機的首頁,也可以用 location 代碼塊來配置
  • access_log 虛擬主機的訪問日志
  • error_log 虛擬主機的錯誤日志
  • error_page 錯誤頁面


server {
listen 80;
server_name localhost;

#access_log logs/host.access.log main;
root "D:/phpStudy/WWW";
location / {
index index.html index.htm index.php l.php;
autoindex off;
}

#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;
}

# 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(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /.ht {
# deny all;
#}
}


2、location 代碼塊

location 代碼塊位于 server 代碼塊內部。

location 用于配置虛擬主機的 URI,它是一個非常重要的配置。


可以給每一個 server(虛擬主機)配置多個 location。


可以根據不同的 URI 配置不同的 location,來處理不同的請求。


2.1、location 的語法格式


其中, = | ~ | ~* | ^~ | @ 表示前綴,也叫修飾符,是可選的;uri 表示普通字符串或正則表達式,是必須的。

@ 這個修飾符非常特殊,后面跟一個普通字符串,用于定義特殊的類型,被定義的類型只能被 nginx 內部調用,用于內部的重定向。這個重定向純碎是 nginx 內部的一個轉發行為。

= 字符串完整匹配。

~ 區分大小寫的正則匹配。

~* 不區分大小寫的正則匹配。

^~ 字符串前綴匹配,只要匹配到了,就不會再匹配其他的正則 location。

如果沒有任何修飾符,也表示字符串前綴匹配,即字符串 location。

如果 location 中使用了修飾符 ~ 或者 ~*,那么,這個 location 就是正則 location;否則,就是字符串 location。

location [ = | ~ | ~* | ^~ | @] uri {...}


2.2、多個 location 的匹配順序


多個 location 的匹配順序與 location 的位置順序沒有直接關系,匹配順序為:


1、= 修飾符的優先級最高,表示完整匹配。如果匹配成功,則停止匹配其他 location。

2、字符串 location 的優先級第二;多個字符串 location 的匹配順序為從長到短,也就是說優先選擇長度最長的字符串匹配;匹配成功的字符串 location 如果使用 了修飾符 ^~ 或者正好是精準匹配,則不會再去檢驗正則 location。

3、正則 location 的優先級低于字符串 location;多個 正則 location 會按照配置文件里的位置順序進行匹配,如果匹配成功,就停止匹配。

注意: 雖然字符串 location 的優先級高于正則 location。但是,如果匹配成功的字符串 location 中沒有使用修飾符 ^~ ,也不是精準匹配,那么還會繼續檢測是否有匹配的正則 location。如果匹配到了正則 location,就立即使用該正則 location 并停止匹配;否則,才會使用字符串 location。


也就是說,匹配到的字符串 location 可能會被正則 location 所覆蓋。


匹配成功的字符串 location,如果不想再繼續檢測匹配正則 location,有三種實現方式:

  • 使用 = 修飾符,來進行完整匹配。
  • 使用 ^~ 修飾符,仍然還是前綴匹配。
  • 如果字符串匹配正好是精準的前綴匹配,也不會再去檢測正則 location。這是一種隱式的實現方式。


2.3、匹配模式及其順序


1、location = /string 字符串完整匹配,優先級最高。

2、location ^~ /string 字符串前綴匹配(不檢測正則 location)。

3、location ~ pattern 正則匹配(區分大小寫)。

4、location ~* pattern 正則匹配(不區分大小寫)。

5、location /string 不帶修飾符的字符串前綴匹配。

6、location / 默認匹配,如果一個請求沒有匹配到其他的 location,就會匹配默認匹配。它相當于 switch 中的 default 。


說明:對于字符串 location,如果沒有 = 修飾符,就都是前綴匹配;而正則 location,可能是前綴匹配、后綴匹配、中間匹配和完整匹配中的任意一種,這取決于正則表達式本身。


2.4、配置默認主頁

location / {
index index.html index.htm index.php l.php;
autoindex off;
}


2.5、配置反向代理


location / {
proxy_pass http://localhost:8888;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


2.6、URL 美化(省略 index.php 入口文件)


location / {
try_files $uri $uri/ /index.php?$query_string;
}


2.7、upstream 代碼塊

upstream 代碼塊位于 http 代碼塊內部。

upstream 用于對服務器集群進行負載均衡的配置。

upstream name { 
ip_hash;
server 192.168.1.100:8000;
server 192.168.1.100:8001 down;
server 192.168.1.100:8002 max_fails=3;
server 192.168.1.100:8003 fail_timeout=20s;
server 192.168.1.100:8004 max_fails=3 fail_timeout=20s;
}
  • ip_hash:手動指定調度算法。
  • down:表示該主機暫停服務。
  • max_fails:表示失敗最大次數,超過失敗最大次數就會暫停服務。
  • fail_timeout:表示如果請求受理失敗,暫停指定的時間之后重新發起請求。


2.8、配置文件中的全局變量


$args #這個變量等于請求行中的參數。

$content_length #請求頭中的Content-length字段。

$content_type #請求頭中的Content-Type字段。

$document_root #當前請求在root指令中指定的值。

$host #請求主機頭字段,否則為服務器名稱。

$http_user_agent #客戶端agent信息

$http_cookie #客戶端cookie信息

$limit_rate #這個變量可以限制連接速率。

$request_body_file #客戶端請求主體信息的臨時文件名。

$request_method #客戶端請求的動作,通常為GET或POST。

$remote_addr #客戶端的IP地址。

$remote_port #客戶端的端口。

$remote_user #已經經過Auth Basic Module驗證的用戶名。

$request_filename #當前請求的文件路徑,由root或alias指令與URI請求生成。

$query_string #與$args相同。

$scheme #HTTP方法(如http,https)。

$server_protocol #請求使用的協議,通常是HTTP/1.0或HTTP/1.1。

$server_addr #服務器地址,在完成一次系統調用后可以確定這個值。

$server_name #服務器名稱。

$server_port #請求到達服務器的端口號。

$request_uri #包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。

$uri #不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。

$document_uri #與$uri相同。


二、Nginx性能調優


1、優化 Nginx工作進程數及連接數

Nginx 有 master 和 worker 兩種進程,master 進程用于管理 worker 進程,worker 進程用于 Nginx 服務。



而worker 進程數默認為 1 。單進程最大連接數為1024。如下圖(打開Nginx目錄下的/conf/nginx.conf 文檔),現在我們來對這兩個數值進行調優



1.1、worker進程設置

worker 進程數應該設置為服務器 CPU 的核數。所以我們得先查看一下本機的CPU核數,得到結果后,再設置上圖中的worker_processes值

# 查看CPU核數
grep -c processor /proc/cpuinfo


1.2、調整最大連接數

控制 Nginx 單個進程允許的最大連接數的參數為 worker_connections ,這個參數要根據服務器性能和內存使用量來調整。

進程的最大連接數受 Linux 系統進程打開的最大文件數的限制,只有執行了 "ulimit -HSn 65535" 之后,worker_connections 才能生效。

連接數包括代理服務器的連接、客戶端的連接等,Nginx 總并發連接數 = worker_processes * worker_connections。總數保持在 3w 左右即可。

worker_processes 2;
worker_cpu_affinity 01 10;
user nginx nginx;
events {
use epoll;
worker_connections 15000;
}


2、綁定 Nginx 進程到不同的 CPU 上

默認情況下,Nginx 的多個進程有可能跑在某一個 CPU 或 CPU 的某一核上,導致 Nginx 進程使用硬件的資源不均,因此綁定 Nginx 進程到不同的 CPU 上是為了充分利用硬件的多 CPU 多核資源。

[[email protected] ~]# 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;

[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload


3、優化 Nginx worker 進程打開的最大文件數

# worker 進程打開的最大文件數,可設置為優化后的 ulimit -HSn 的結果
worker_rlimit_nofile 65535;


4、開啟高效文件傳輸模式

sendfile:參數用于開啟文件的高效傳輸模式,該參數實際上是激活了 sendfile() 功能。

sendfile() :是作用于兩個文件描述符之間的數據拷貝函數,這個拷貝操作是在內核之中的,被稱為 "零拷貝" 。sendfile 比 read 和 write 函數要高效得多,因為 read 和 write 函數要把數據拷貝到應用層再進行操作。

tcp_nopush:參數用于激活 Linux 上的 TCP_CORK socket 選項,此選項僅僅當開啟 sendfile 時才生效,tcp_nopush 參數可以把 http response header 和文件的開始部分放在一個文件里發布,以減少網絡報文段的數量。

http {
include mime.types;
default_type application/octet-stream;

sendfile on; # 開啟文件的高效傳輸模式,減少文件在應用和內核之間的拷貝
tcp_nopush on; # 激活 TCP_CORK socket 選擇,當數據包達到一定大小再發送
tcp_nodelay on; # 數據在傳輸的過程中不進緩存,有數據隨時發送(只用在應答需要非常快速的情況下)

keepalive_timeout 65;
include vhosts/*.conf;
}


5、優化 Nginx 連接的超時時間

5.1:連接超時的作用

  • 將無用的連接設置為盡快超時,可以保護服務器的系統資源(CPU、內存、磁盤)
  • 當連接很多時,及時斷掉那些建立好的但又長時間不做事的連接,以減少其占用的服務器資源
  • 如果黑客攻擊,會不斷地和服務器建立連接,因此設置連接超時以防止大量消耗服務器的資源
  • 如果用戶請求了動態服務,則 Nginx 就會建立連接,請求 FastCGI 服務以及后端 MySQL 服務,設置連接超時,使得在用戶容忍的時間內返回數據

5.2:連接超時存在的問題

  • 服務器建立新連接是要消耗資源的,因此,連接超時時間不宜設置得太短,否則會造成并發很大,導致服務器瞬間無法響應用戶的請求。
  • 有些 PHP 站點會希望設置成短連接,因為 PHP 程序建立連接消耗的資源和時間相對要少些。
  • 有些 Java 站點會希望設置成長連接,因為 Java 程序建立連接消耗的資源和時間要多一些,這是由語言的運行機制決定的。


5.3:設置超時時間

  • keepalive_timeout:用于設置客戶端連接保持會話的超時時間,超過這個時間服務器會關閉該連接。
  • client_header_timeout:用于設置讀取客戶端請求頭數據的超時時間,如果超時客戶端還沒有發送完整的 header 數據,服務器將返回 "Request time out (408)" 錯誤。
  • client_body_timeout:用于設置讀取客戶端請求主體數據的超時時間,如果超時客戶端還沒有發送完整的主體數據,服務器將返回 "Request time out (408)" 錯誤。
  • send_timeout:用于指定響應客戶端的超時時間,如果超過這個時間,客戶端沒有任何活動,Nginx 將會關閉連接。
  • tcp_nodelay:默認情況下當數據發送時,內核并不會馬上發送,可能會等待更多的字節組成一個數據包,這樣可以提高 I/O 性能,但是,在每次只發送很少字節的業務場景中,使用 tcp_nodelay 功能,等待時間會比較長。
http {
include mime.types;
server_names_hash_bucket_size 512;

default_type application/octet-stream;
sendfile on;
tcp_nodelay on;

keepalive_timeout 65;
client_header_timeout 15;
client_body_timeout 15;
send_timeout 25;

include vhosts/*.conf;
}


6、限制上傳文件的大小


client_max_body_size 用于設置最大的允許客戶端請求主體的大小。

在請求頭中有 "Content-Length" ,如果超過了此配置項,客戶端會收到 413 錯誤,即請求的條目過大。

http {
client_max_body_size 8m; # 設置客戶端最大的請求主體大小為 8 M

}


7、FastCGI 相關參數調優


當 LNMP 組合工作時,用戶通過瀏覽器輸入域名請求 Nginx Web 服務:

  • 如果請求的是靜態資源,則由 Nginx 解析后直接返回給用戶;
  • 如果是動態請求(如 PHP),那么 Nginx 就會把它通過 FastCGI 接口發送給 PHP 引擎服務(即 php-fpm)進行解析,如果這個動態請求要讀取數據庫數據,那么 PHP 就會繼續請求 MySQL 數據庫,以讀取需要的數據,并最終通過 Nginx 服務把獲取的數據返回給用戶。

這就是 LNMP 環境的基本請求流程。

在 Linux 中,FastCGI 接口即為 socket ,這個 socket 可以是文件 socket,也可以是 IP socket。

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
}
}
}


8、gzip 壓縮(在之前的講解vue首頁加載慢的一文中也有介紹Nginx壓縮)


Nginx gzip 壓縮模塊提供了壓縮文件內容的功能,用戶請求的內容在發送到客戶端之前,Nginx 服務器會根據一些具體的策略實施壓縮,以節約網站出口帶寬,同時加快數據傳輸效率,來提升用戶訪問體驗。

需要壓縮的對象有 html 、js 、css 、xml 、shtml ,圖片和視頻盡量不要壓縮,因為這些文件大多都是已經壓縮過的,如果再壓縮可能反而變大。

另外,壓縮的對象必須大于 1KB,由于壓縮算法的特殊原因,極小的文件壓縮后可能反而變大。

http {
gzip on; # 開啟壓縮功能
gzip_min_length 1k; # 允許壓縮的對象的最小字節
gzip_buffers 4 32k; # 壓縮緩沖區大小,表示申請4個單位為32k的內存作為壓縮結果的緩存
gzip_http_version 1.1; # 壓縮版本,用于設置識別HTTP協議版本
gzip_comp_level 9; # 壓縮級別,1級壓縮比最小但處理速度最快,9級壓縮比最高但處理速度最慢
gzip_types text/plain application/x-javascript text/css application/xml; # 允許壓縮的媒體類型
gzip_vary on; # 該選項可以讓前端的緩存服務器緩存經過gzip壓縮的頁面,例如用代理服務器緩存經過Nginx壓縮的數據
}


9、配置 expires 緩存期限


Nginx expires 的功能就是給用戶訪問的靜態內容設定一個過期時間。

當用戶第一次訪問這些內容時,會把這些內容存儲在用戶瀏覽器本地,這樣用戶第二次及以后繼續訪問該網站時,瀏覽器會檢查加載已經緩存在用戶瀏覽器本地的內容,就不會去服務器下載了,直到緩存的內容過期或被清除。

不希望被緩存的內容:廣告圖片、網站流量統計工具、更新很頻繁的文件。

緩存期限參考:新浪緩存 15 天,京東緩存 25 年,淘寶緩存 10 年。

server {
listen 80;
server_name www.abc.com abc.com;
root html/www;
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|js|css)$ # 緩存的對象
{
expires 3650d; # 緩存期限為 10 年
}
}


10、配置防盜鏈


防盜鏈:簡單地說,就是其它網站未經許可,通過在其自身網站程序里非法調用其他網站的資源,然后在自己的網站上顯示這些調用的資源,使得被盜鏈的那一端消耗帶寬資源 。

通過 HTTP referer 實現防盜鏈。

#第一種,匹配后綴
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 none blocked *.spdir.com *.spdir.top;
if ($invalid_referer) {
return 403;
}
}


11、操作系統優化

1、配置文件/etc/sysctl.conf,如下:

sysctl -w net.ipv4.tcp_syncookies=1 #防止一個套接字在有過多試圖連接到達時引起過載
sysctl -w net.core.somaxconn=1024 #默認128,連接隊列
sysctl -w net.ipv4.tcp_fin_timeout=10 #timewait的超時時間
sysctl -w net.ipv4.tcp_tw_reuse=1 #os直接使用timevait的連接
sysctl -w net.ipv4.tcp_tw_recycle=0 #回收禁用

2、配置文件/etc/security/limits.conf,如下:

hard nofile 204800
soft nofile 204800
soft core unlimited
soft stack 204800


小編推薦:欲學習電腦技術、系統維護、網絡管理、編程開發和安全攻防等高端IT技術,請 點擊這里 注冊賬號,公開課頻道價值萬元IT培訓教程免費學,讓您少走彎路、事半功倍,好工作升職加薪!

本文出自:https://www.toutiao.com/a6765746230141125132/

免責聲明:本站系公益性非盈利IT技術普及網,本文由投稿者轉載自互聯網的公開文章,文末均已注明出處,其內容和圖片版權歸原網站或作者所有,文中所述不代表本站觀點,若有無意侵權或轉載不當之處請從網站右下角聯系我們處理,謝謝合作!


鮮花

握手

雷人

路過

雞蛋

相關閱讀

最新評論

 最新
返回頂部
洗衣店赚钱联系澳洁