天天看點

Nginx 配置和性能調優fastcti_temp_path /data/ngx_fcgi_tmp; # FastCGI 臨時檔案的存放路徑

優化 Nginx worker 程序數

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

worker 程序數預設為 1 。

worker_processes 1;

worker 程序數應該設定為伺服器 CPU 的核數。

root@localhost ~# grep -c processor /proc/cpuinfo # 檢視CPU核數

2

root@localhost ~# vim /usr/local/nginx/conf/nginx.conf # 設定worker程序數

worker_processes 2;

worker_processes 這個參數最好是設定成 auto 自動比對程序數。

綁定 Nginx 程序到不同的 CPU 上

預設情況下,Nginx 的多個程序有可能跑在某一個 CPU 或 CPU 的某一核上,導緻 Nginx 程序使用硬體的資源不均,是以綁定 Nginx 程序到不同的 CPU 上是為了充分利用硬體的多 CPU 多核資源。

root@localhost ~# 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;

優化 Nginx 單個程序允許的最大連接配接數

控制 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;           

複制

}

優化 Nginx worker 程序打開的最大檔案數

worker_rlimit_nofile 65535; # worker 程序打開的最大檔案數,可設定為優化後的 ulimit -HSn 的結果

開啟高效檔案傳輸模式

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;

}

優化 Nginx 連接配接的逾時時間

連接配接逾時的作用

将無用的連接配接設定為盡快逾時,可以保護伺服器的系統資源(CPU、記憶體、磁盤)

當連接配接很多時,及時斷掉那些建立好的但又長時間不做事的連接配接,以減少其占用的伺服器資源

如果黑客攻擊,會不斷地和伺服器建立連接配接,是以設定連接配接逾時以防止大量消耗伺服器的資源

如果使用者請求了動态服務,則 Nginx 就會建立連接配接,請求 FastCGI 服務以及後端 MySQL 服務,設定連接配接逾時,使得在使用者容忍的時間内傳回資料

連接配接逾時存在的問題

伺服器建立新連接配接是要消耗資源的,是以,連接配接逾時時間不宜設定得太短,否則會造成并發很大,導緻伺服器瞬間無法響應使用者的請求。

有些 PHP 站點會希望設定成短連接配接,因為 PHP 程式建立連接配接消耗的資源和時間相對要少些。

有些 Java 站點會希望設定成長連接配接,因為 Java 程式建立連接配接消耗的資源和時間要多一些,這是由語言的運作機制決定的。

設定逾時時間

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;           

複制

}

限制上傳檔案的大小

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

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

http {

client_max_body_size 8m;    # 設定用戶端最大的請求主體大小為 8 M           

複制

}

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           

複制

}           

複制

}           

複制

}

gzip 壓縮

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壓縮的資料           

複制

}

配置 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 年           

複制

}           

複制

}

配置防盜鍊

什麼是防盜鍊?

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

通過 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;           

複制

}           

複制

}

server 代碼塊

server 代碼塊位于 http 代碼塊内部,每一個 server 都可以用來配置一個虛拟主機。也就是說,每一個 server 代表了一個虛拟伺服器的配置資訊。

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

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;           

複制

#}           

複制

}

server 中的主要配置有:

listen 虛拟主機監聽的端口

server_name 虛拟主機的域名或 IP 位址,可以配置多個(用空格隔開)

root 虛拟主機的根目錄

index 虛拟主機的首頁,也可以用 location 代碼塊來配置

access_log 虛拟主機的通路日志

error_log 虛拟主機的錯誤日志

error_page 錯誤頁面

location 代碼塊

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

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

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

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

location 的文法格式

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

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

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

= 字元串完整比對。

~ 區分大小寫的正則比對。

~* 不區分大小寫的正則比對。

^~ 字元串字首比對,隻要比對到了,就不會再比對其他的正則 location。

如果沒有任何修飾符,也表示字元串字首比對,即字元串 location。

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

多個 location 的比對順序

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

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

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

正則 location 的優先級低于字元串 location;多個 正則 location 會按照配置檔案裡的位置順序進行比對,如果比對成功,就停止比對。

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

也就是說,比對到的字元串 location 可能會被正則 location 所覆寫。

比對成功的字元串 location,如果不想再繼續檢測比對正則 location,有三種實作方式:

使用 = 修飾符,來進行完整比對。

使用 ^~ 修飾符,仍然還是字首比對。

如果字元串比對正好是精準的字首比對,也不會再去檢測正則 location。這是一種隐式的實作方式。

比對模式及其順序

location = /string 字元串完整比對,優先級最高。

location ^~ /string 字元串字首比對(不檢測正則 location)。

location ~ pattern 正則比對(區分大小寫)。

location ~* pattern 正則比對(不區分大小寫)。

location /string 不帶修飾符的字元串字首比對。

location / 預設比對,如果一個請求沒有比對到其他的 location,就會比對預設比對。它相當于 switch 中的 default 。

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

配置預設首頁

location / {

index   index.html index.htm index.php l.php;           

複制

autoindex  off;           

複制

}

配置反向代理

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;            

複制

}

URL 美化(省略 index.php 入口檔案)

location / {

try_files $uri $uri/ /index.php?$query_string;           

複制

}

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:表示如果請求受理失敗,暫停指定的時間之後重新發起請求。

配置檔案中的全局變量

$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 相同。

源碼附件已經打包好上傳到百度雲了,大家自行下載下傳即可~

連結: https://pan.baidu.com/s/14G-bpVthImHD4eosZUNSFA?pwd=yu27

提取碼: yu27

百度雲連結不穩定,随時可能會失效,大家抓緊儲存哈。

如果百度雲連結失效了的話,請留言告訴我,我看到後會及時更新~

開源位址

碼雲位址:

http://github.crmeb.net/u/defu

Github 位址:

http://github.crmeb.net/u/defu