七年開發經驗Nginx功能詳解
一、proxy_pass
在nginx中配置proxy_pass代理轉發時,如果在proxy_pass後面的url加/,表示絕對根路徑;如果沒有/,表示相對路徑,把匹配的路徑部分也給代理走。
假設下面四種情況分別用 http://192.168.1.1/proxy/test.html 進行訪問。
第一種:
location /proxy/ {
proxy_pass http://127.0.0.1/;
}
代理到URL:http://127.0.0.1/test.html
第二種(相對於第一種,最後少一個 / )
location /proxy/ {
proxy_pass http://127.0.0.1;
}
代理到URL:http://127.0.0.1/proxy/test.html
第三種:
location /proxy/ {
proxy_pass http://127.0.0.1/aaa/;
}
代理到URL:http://127.0.0.1/aaa/test.html
第四種(相對於第三種,最後少一個 / )
location /proxy/ {
proxy_pass http://127.0.0.1/aaa;
}
代理到URL:http://127.0.0.1/aaatest.html
第五種 配合upstream模組
如果一個域名可以解析到多個地址,那麼這些地址會被輪流使用,此外,還可以把一個地址指定為 server group
upstream acs.gwmfc.com {
server 10.5.1.20:17007 max_fails=2 fail_timeout=15s;
server 10.5.1.21:17007 max_fails=2 fail_timeout=15s down;
ip_hash;
}
server {
listen 9000;
server_name ACS-NGINX-P01;
location / {
proxy_pass http://acs.gwmfc.com;
proxy_read_timeout 300;
proxy_connect_timeout 90;
proxy_send_timeout 300;
proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
} X_Forward_For欄位表示該條http請求是有誰發起的?如果反向代理伺服器不重寫該請求頭的話,那麼後端真實伺服器在處理時會認為所有的請求都來在反向代理伺服器,如果後端有防攻擊策略的話,那麼機器就被封掉了(顯示真實訪問ip)
二、rewrite
syntax: rewrite regex replacement [flag]
rewrite由ngx_http_rewrite_module標準模組支援是實現URL重定向的重要指令,他根據regex(正則表示式)來匹配內容跳轉到replacement,結尾是flag標記
簡單的小例子:
1.rewrite ^/(.*) http://www.baidu.com/ permanent; # 匹配成功後跳轉到百度,執行永久301跳轉
常用正則表示式regex :
字元 描述
將後面接著的字元標記為一個特殊字元或者一個原義字元或一個向後引用
^ 匹配輸入字串的起始位置
$ 匹配輸入字串的結束位置
* 匹配前面的字元零次或者多次
+ 匹配前面字串一次或者多次
? 匹配前面字串的零次或者一次
. 匹配除“ ”之外的所有單個字元
(pattern) 匹配括號內的pattern
rewrite 最後一項flag引數:
標記符號 說明
last 本條規則匹配完成後繼續向下匹配新的location URI規則
break 本條規則匹配完成後終止,不在匹配任何規則
redirect 返回302臨時重定向
permanent 返回301永久重定向
在反向代理域名的使用,在tomcat中配置多個專案需要掛目錄的使用案例:
server {
listen 443;
server_name FLS-Nginx-P01;
ssl on;
ssl_certificate cert/214837463560686.pem;
ssl_certificate_key cert/214837463560686.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location = / {
rewrite ^(.*)$ https://fls.orafl.com/fls/;
}
location / {
proxy_redirect http https;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
proxy_pass http://10.6.3.4:8080;
}
}
公網域名解析fls.orafl.com
三、log_format
nginx伺服器日誌相關指令主要有兩條:一條是log_format,用來設定日誌格式;另外一條是access_log,用來指定日誌檔案的存放路徑、格式和快取大小,可以參加ngx_http_log_module。一般在nginx的配置檔案中日記配置(/usr/local/nginx/conf/nginx.conf)
log_format指令用來設定日誌的記錄格式,它的語法如下:
log_format name format {format ...}
其中name表示定義的格式名稱,format表示定義的格式樣式。
log_format有一個預設的、無須設定的combined日誌格式設定,相當於Apache的combined日誌格式,其具體引數如下:
log_format combined '$remote_addr-$remote_user [$time_local]'
‘"$request"$status $body_bytes_sent’
‘"$http_referer" "$http_user_agent"’
也可以自定義一份日誌的記錄格式,不過要注意,log_format指令設定的名稱在配置檔案中是不能重複的。
四、ssl證書加密配置
upstream acs.gwmfc.com {
server 10.5.1.*:17007 max_fails=2 fail_timeout=15s;
server 10.5.1.*:17007 max_fails=2 fail_timeout=15s down;
ip_hash; ----同一ip會被分配給固定的後端伺服器,解決session問題
}
server {
listen 443;
server_name ACS-NGINX-P01;
ssl on;
ssl_certificate 214820781820381.pem; 證書路徑:nginx.conf所在目錄
ssl_certificate_key 214820781820381.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://acs.gwmfc.com;
proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
}
}
五、sendfile
sendfile: 設定為on表示啟動高效傳輸檔案的模式。sendfile可以讓Nginx在傳輸檔案時直接在磁碟和tcp socket之間傳輸資料。如果這個引數不開啟,會先在使用者空間(Nginx程序空間)申請一個buffer,用read函式把資料從磁碟讀到cache,再從cache讀取到使用者空間的buffer,再用write函式把資料從使用者空間的buffer寫入到核心的buffer,最後到tcp socket。開啟這個引數後可以讓資料不用經過使用者buffer。
六、keepalive_timeout
當上傳一個發資料檔案時,nginx往往會超時,此時需要調整keepalive_timeout引數,保持會話長連結
七、gzip
如果你是個前端開發人員,你肯定知道線上環境要把js,css,圖片等壓縮,儘量減少檔案的大小,提升響應速度,特別是對移動端,這個非常重要。
gzip使用環境:http,server,location,if(x),一般把它定義在nginx.conf的http{…..}之間
gzip on
on為啟用,off為關閉
gzip_min_length 1k
設定允許壓縮的頁面最小位元組數,頁面位元組數從header頭中的Content-Length中進行獲取。預設值是0,不管頁面多大都壓縮。建議設定成大於1k的位元組數,小於1k可能會越壓越大。
gzip_buffers 4 16k
獲取多少記憶體用於快取壓縮結果,‘4 16k’表示以16k*4為單位獲得
gzip_comp_level 5
gzip壓縮比(1~9),越小壓縮效果越差,但是越大處理越慢,所以一般取中間值;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php
對特定的MIME型別生效,其中'text/html’被系統強制啟用
gzip_http_version 1.1
識別http協議的版本,早起瀏覽器可能不支援gzip自解壓,使用者會看到亂碼
gzip_vary on
啟用應答頭"Vary: Accept-Encoding"
gzip_proxied off
nginx做為反向代理時啟用,off(關閉所有代理結果的資料的壓縮),expired(啟用壓縮,如果header頭中包括"Expires"頭資訊),no-cache(啟用壓縮,header頭中包含"Cache-Control:no-cache"),no-store(啟用壓縮,header頭中包含"Cache-Control:no-store"),private(啟用壓縮,header頭中包含"Cache-Control:private"),no_last_modefied(啟用壓縮,header頭中不包含"Last-Modified"),no_etag(啟用壓縮,如果header頭中不包含"Etag"頭資訊),auth(啟用壓縮,如果header頭中包含"Authorization"頭資訊)
gzip_disable msie6
(IE5.5和IE6 SP1使用msie6引數來禁止gzip壓縮 )指定哪些不需要gzip壓縮的瀏覽器(將和User-Agents進行匹配),依賴於PCRE庫
以上程式碼可以插入到 http {...}整個伺服器的配置裡,也可以插入到虛擬主機的 server {...}或者下面的location模組內
八、客戶端上傳檔案限制
client_body_buffer_size 15M;
請求緩衝區在NGINX請求處理中起著重要作用。 在接收到請求時,NGINX將其寫入這些緩衝區,此指令設定用於請求主體的緩衝區大小。 如果主體超過緩衝區大小,則完整主體或其一部分將寫入臨時檔案。 如果NGINX配置為使用檔案而不是記憶體緩衝區,則該指令會被忽略。 預設情況下,該指令為32位系統設定一個8k緩衝區,為64位系統設定一個16k緩衝區
client_body_temp_path clientpath 3 2;
關於client_body_temp目錄的作用,簡單說就是如果客戶端POST一個比較大的檔案,長度超過了nginx緩衝區的大小,需要把這個檔案的部分或者全部內容暫存到client_body_temp目錄下的臨時檔案。
後面的level1,2,3是什麼意思?
因為如果所有上傳的檔案都放在一個資料夾下,不僅很容易檔名衝突,並且容易導致一個資料夾特別大。
所以有必要建立子目錄
這裡的level1,2,3如果有值就代表存在一級,二級,三級子目錄。
目錄名是由數字進行命名的,所以這裡的具體的值就是代表目錄名的數字位數
比如
client_body_temp_path /spool/nginx/client_temp 3 2;
可能建立的檔案路徑為
/spool/nginx/client_temp/702/45/00000123457
client_max_body_size 30M;
此指令設定NGINX能處理的最大請求主體大小。 如果請求大於指定的大小,則NGINX發回HTTP 413(Request Entity too large)錯誤。 如果伺服器處理大檔案上傳,則該指令非常重要。
九、worker_processes和worker_connections
worker_processes :作業系統啟動多少個工作程序執行Nginx。注意是工作程序,不是有多少個nginx工程。在Nginx執行的時候,會啟動兩種程序,一種是主程序master process;一種是工作程序worker process。例如我在配置檔案中將worker_processes設定為4,啟動Nginx後,使用程序檢視命令觀察名字叫做nginx的程序資訊,我會看到如下結果:1個nginx主程序,master process;還有四個工作程序,worker process。主程序負責監控埠,協調工作程序的工作狀態,分配工作任務,工作程序負責進行任務處理。一般這個引數要和作業系統的CPU核心數成倍數。可以設定為auto自動識別
worker_connections :這個屬性是指單個工作程序可以允許同時建立外部連線的數量。無論這個連線是外部主動建立的,還是內部建立的。這裡需要注意的是,一個工作程序建立一個連線後,程序將開啟一個檔案副本。所以這個數量還受作業系統設定的,程序最大可開啟的檔案數有關 。
十、stream模組
nginx從1.9.0開始,新增加了一個stream模組,用來實現四層協議的轉發、代理或者負載均衡等。這完全就是搶HAproxy份額的節奏,鑑於nginx在7層負載均衡和web service上的成功,和nginx良好的框架,stream模組前景一片光明
stream模組預設沒有編譯到nginx, 編譯nginx時候 ./configure –with-stream 即可
stream模組用法和http模組差不多,關鍵的是語法幾乎一致。熟悉http模組配置語法的上手更快
以下是一個配置了tcp負載均衡和udp(dns)負載均衡的例子, 有 server,upstream塊,而且還有server,
hash, listen, proxy_pass等指令,如果不看最外層的stream關鍵字,還以為是http模組呢,下例是四層反代郵箱協議的例子,直寫了25埠,其他埠方法相同
stream {
upstream smtp {
least_conn; ------把請求轉發給連線數較少的後端,能夠達到更好的負載均衡效果
server 10.5.3.17:25 max_fails=2 fail_timeout=10s;
}
server {
listen 25;
proxy_pass smtp;
proxy_timeout 3s;
proxy_connect_timeout 1s;
}
寫在最後:歡迎留言討論,加關注,持續更新!!!