上篇博文介紹了Nginx的做爲http服務器的配置,下面介紹下Nginx的反向代理配置。
ngx_http_proxy_module
1.proxy_pass URL;
上下文:location, if in location, limit_except
proxy_pass後面的路徑不帶uri時,其會將location的uri傳遞給後端主機;
location /uri/ {
proxy_pass http://HOST;
}
proxy_pass後面路徑是一個uri時,其會將location的uri替換爲proxy_pass後端主機的uri;
location /uri/ {
proxy_pass http://HOST/new_uri/;
}
如果location定義其uri時使用了正則表達模式匹配機制,則proxy_pass後的路徑必須不能使用uri;
location ~|~* PATTERN {
proxy_pass http://HOST;
}
http://www.magedu.com/bbs/ --> http://172.16.100.7/bbs/
http://www.magedu.com/bbs/ --> http://172.16.100.7/
示例1.當後端定義爲主機不加URL時,直接轉到服務器上location對應URL上:
location / { index index.html; proxy_pass http://172.18.29.140; } # curl http://172.18.29.142/index.html
示例2.當後端定義爲主機加URL時,重寫location對應URL到後端:
location / { index index.html; proxy_pass http://172.18.29.140/admin/; } # curl http://172.18.29.142/index.html admin index page @server140
示例3.location匹配正則時,proxy_pass 指定後端主機不能添加uri;
location ~/.*\\.jpg { index index.html; proxy_pass http://172.18.29.140; } # curl -I http://172.18.29.142/1.jpg HTTP/1.1 200 OK Server: nginx/1.0.15 Date: Thu, 19 May 2016 07:42:41 GMT Content-Type: p_w_picpath/jpeg Connection: keep-alive Content-Length: 931957 Last-Modified: Wed, 11 May 2016 07:55:14 GMT Accept-Ranges: bytes
示例4.這裏視圖爲後端主機添加URL時,產生錯誤,就如上所說;看起來很不方便,實際上若要求需要在後端主機建立對應路徑映射的虛擬主機才行!
location ~/.*\\.jpg { index index.html; proxy_pass http://172.18.29.140/; } # nginx -t nginx: [emerg] "proxy_pass" may not have URI part in location given by regular expression, or inside named location, or inside the "if" statement, or inside the "limit_except" block in /etc/nginx/nginx.conf:22 nginx: configuration file /etc/nginx/nginx.conf test failed
2.proxy_set_header
可用於上下文:http
, server
, location
proxy_set_header field value;
設定向後端主機發送的請求報文的首部及其值;
示例:
將遠端客戶端IP地址添加到報文首部,傳遞給後端主機;
proxy_set_header X-Real-IP $remote_addr;
將真正的請求客戶端地址放置在X-Forwarded-For中傳遞到後端服務器,效果和前者一樣。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
在修改之前,後端主機記錄都是代理服務器地址,爲了統計訪問行爲,這裏需要修改:
# 這裏從140服務器上訪問http://172.18.29.142/1.jpg,之前的日誌: 172.18.29.142 - - [25/May/2016:21:15:42 +0800] "HEAD /1.jpg HTTP/1.0" 200 - "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" # 添加報文首部,並修改後端日誌記錄格式 ## 代理添加報頭,可以在http,server,location中使用 proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; ## 修改後端主機日誌格式,這裏時httpd的日誌,生產中一般也是如此; LogFormat "%{X-Forward-For}i %l %u %t \\"%r\\" %>s %b \\"%{Referer}i\\" \\"%{User-Agent}i\\"" combined #tail /var/log/http/access.log 172.18.29.140 - - [25/May/2016:21:21:18 +0800] "HEAD /1.jpg HTTP/1.0" 200 - "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" ## 可以看到這顯示真實請求主機的地址
緩存相關的選項(緩存要先定義,後調用)
1.proxy_cache_path
proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] ;
用於http上下文 ,定義一個代理緩存路徑,也稱爲zone;
2.proxy_cache ZONE | off;
調用緩存,默認爲off;ZONE指代緩存路徑。
3.proxy_cache_key string;
定義緩存鍵;
proxy_cache_key $request_uri
proxy_cache_key $scheme$proxy_host$request_uri
4.proxy_cache_valid [code ...] time
爲不同的響應碼設定其緩存的時長;
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
5.proxy_cache_use_stale
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
當於後端主機鏈接出錯時,決定什麼時候失效的緩存是可用來響應的
proxy_cache_path /var/cache/nginx/proxy_cache levels=2:1 keys_zone=proxy:1m;
server {
....
location / {
# root html;
proxy_pass http://172.18.29.140/admin/;
index index.html index.htm;
proxy_cache proxy;
proxy_cache_key $request_uri;
proxy_cache_valid 200 10m;
}
示例:使用代理緩存
http { include mime.types; default_type application/octet-stream; proxy_cache_path /var/cache/nginx/proxy_cache levels=2:1 keys_zone=http:1m inactive=1h max_size=100m; server { proxy_cache http; proxy_cache_valid 200 302 10m; proxy_cache_key $request_uri; proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; listen 172.18.29.142:80; server_name www.magedu.com; root /data/webs/v1; index index.html; location / { proxy_pass http://172.18.29.141; } ... ... }
請求http://172.18.29.142/index.html後查看緩存爲位置:
# pwd /var/cache/nginx/proxy_cache # ll total 8 drwx------ 3 nginx nginx 4096 May 19 16:52 a4 drwx------ 3 nginx nginx 4096 May 19 16:52 d9
ngx_http_headers_module
用於在響應給客戶端的報文中添加首部;
(1) add_header name value [always];
上下文:http, server, location, if in location
向響應報文添加自定義首部,並賦值;
add_header X-Via $server_addr;
如果指定always那麼就是所有狀態都添加該header,默認爲200+ 300+ 部分添加。
示例:在響應報文中添加代理主機IP報文首部
http{ ... add_header X-Via $server_addr; ... } # curl -I http://172.18.29.142/ HTTP/1.1 200 OK Server: nginx/1.0.15 Date: Thu, 19 May 2016 09:03:05 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Last-Modified: Tue, 24 May 2016 02:30:07 GMT ETag: "e0fae-14-5338d55e359cd" Content-Length: 20 X-Via: 172.18.29.142 Accept-Ranges: bytes # 可以看到X-Via首部
ngx_http_upstream_module
將多個後端主機定義爲服務器組,而後可由proxy_pass, fastcgi_pass, memcached_pass等進行引用;調用方式如:
prioxy_pass http://webs
(1) upstream name { ... }
定義後端服務器組;引入新的上下文;只能用於http上下文;
name:名稱,直接字符串;
(2) server
server address [parameters];
定義服務器的地址和相關的參數;
地址格式:
IP[:port]
HOSTNAME[:port]
unix:/PATH/TO/SOME_SOCK_FILE
參數:
weight=number:服務器權重;
max_fails=number:最大失敗嘗試次數;
fail_timeout=time:設置服務器不可用超時時長;
backup:備用主機;
down:手動標記其不再處理任何用戶請求;
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
(3) ip_hash;
源地址哈希調度算法;
(4) least_conn;
最少連接調度算法;
(5) health_check [parameters]; (僅僅2.0版本支持)
定義後端主機的健康狀態檢測機制;只能用於location上下文;
可用參數:
interval=#:檢測的頻度,默認爲5秒;
fails=number:判定爲失敗的檢測次數;
passes=number:判定爲成功的檢測次數;
uri=uri:執行健康狀態檢測時請求的uri;
match=name:基於哪個match做檢測結果爲“成功”或“失敗”的判定;
port=number:向服務器的哪個端口發起健康狀態檢測請求;
說明:health_check 參數中指定其他端口,健康狀態檢測可能不希望被記錄到日誌中,可以設置另外一個虛擬主機上
(6) match name { ... }
僅能用於http上下文 ;對後端主機做健康狀態檢測時,定義其結果判斷標準;
專用指令:
status:期望的響應碼;
status CODE
status ! CODE
status CODE-CODE
header:基於響應首部進行判斷
header HEADER=VALUE
header HEADER!=VALUE
header [!] HEADER
header HEADER ~ VALUE
body:期望的響應報文的主體部分應該有的內容;
body ~ "CONTENT"
body !~ "CONTENT"
(7) hash key [consistent];
定義調度方法,可自定義基於何種信息(key)進行綁定;
hash $remote_addr
hash $request_uri
hash $cookie_username
hash key 可以根據某個字段哈希綁定到固定服務器,其中目標uri可以放置在nginx調度緩存服務器時使用:訪問同一個頁面都會指定到某個固定服務器上。
upstream websrv { ip_hash; server 172.18.29.141:80 max_fails=3; server 172.18.29.140:80; } 訪問 該主機將不會再次被調度到down的主機。所以nginx做負載均衡時,可以很平滑的處理,不影響線上。 match name { ... } 僅能用於http上下文 ;對後端主機做健康狀態檢測時,定義其結果判斷標準; 專用指令: status:期望的響應碼; status CODE status ! CODE status CODE-CODE header:基於響應首部進行判斷 header HEADER=VALUE header HEADER!=VALUE header [!] HEADER header HEADER ~ VALUE body:期望的響應報文的主體部分應該有的內容; body ~ "CONTENT" body !~ "CONTENT"