Nginx 之 實現代理功能
1 概述
ngx_http_proxy_module模塊允許將請求傳遞給另一個服務器,也可以充當應用級的反向代理。根據應用進行調度。訪問的時候,服務器認為是代理服務器訪問的,如果要看真實的訪問者,需要到代理服務器上的log去訪問.這個可以通過proxy_set_header這個命令進行配置,使得在提供服務的服務器器上查看到真實的客戶端ip.
2 配置介紹
1、proxy_pass
proxy_pass URL;
Context:location, if in location,limit_except
註意:proxy_pass後面的路徑不帶uri時,其會將location的uri傳遞給後端主機
server { ... server_name HOSTNAME; location /uri/ { proxy_pass http://host[:port]; #最後沒有/ } ... }
上面示例:http://HOSTNAME/uri--> http://host/uri
.proxy_pass後面的路徑是一個uri時,其會將location的uri替換為proxy_pass的uri
server { ... server_name HOSTNAME; location /uri/ { proxy_pass http://host/new_uri/; #最後有/ } ... }
如:http://HOSTNAME/uri/ --> http://host/new_uri/
例子:
location /fujian { proxy_pass http://172.18.50.75/; }
註意:75後面加了
例子:
location /fujian { proxy_pass http://172.18.50.75; }
註意:75後面沒有/斜線,訪問curl 172.18.50.73/fujian/,就會把fujian直接補充到後面,即實際訪問http:// 172.18.50.73/fujian/index.html。此時,要要求在跳轉後的服務器在對應的主目錄下也要有fujian這個文件夾,否則訪問會出錯
正則表達式使用註意
.如果location定義其uri時使用了正則表達式的模式,則
server { ... server_name HOSTNAME; location ~|~* /uri/{ proxy_pass http://host; 不能加/ } ... }
例子
location,用了正則表達式,則location的的url不能跟斜線,否則重啟nginx服務會報錯,如下
location ~ \.txt$ { proxy_pass http://172.18.50.75/; }
重啟nginx服務報錯如下
nginx: [emerg]"proxy_pass" cannot have URI part in location given by regularexpression, or inside named location, or inside "if" statement, orinside "limit_except" block in /etc/nginx/conf.d/server.conf:14
因為此時logcation後用了正則表達式,那麽,172.18.50.75後面有斜杠是錯誤的寫法,這種情況,符合該條件資源的文件在後端的服務器上一定要存在,因為是對url做了補全,不是替換
正確寫法
location ~ \.txt$ { proxy_pass http://172.18.50.75; }
比如訪問curl172.18.50.73/m.txt,172.18.50.73這臺服務器在家目錄下可以沒有m.txt,但是,在服務器172.18.50.75這臺的主目錄下要有m.txt,否則無法訪問,因為實際會調度到後端的http://172.18.50.75/m.txt這個資源。
.2、proxy_set_header
proxy_set_header field value;
設定發往後端主機的請求報文的請求首部的值,即人為添加一個字段,同時在後端的服務器上要更改日誌信息的格式,這樣後端服務器才能記錄相應的log。
Context: http, server, location
proxy_set_header X-Real-IP $remote_addr;
# X-Real-IP可以自己定義
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$proxy_add_x_forwarded_for 如果在nginx前端還有調度器,那麽就會一次把前端的調度器用逗號依次隔開
標準格式如下:
X-Forwarded-For: client1, proxy1,proxy2
例子:
在調度的nginx服務器上,配置文件寫入如下配置, proxy_set_header後面的sunny_ip可以自定義,但是在服務器端定義日誌格式時要一致
location ~ \.txt$ { proxy_passhttp://172.18.50.75; proxy_set_header sunny_ip $remote_addr; }
在後端提供服務的服務器上172.18.50.75,修改配置文件如下,
首先,定義日誌格式,註意%{sunny_ip}i 這裏花括號裏的sunny_ip一定是要和服務器設置的一樣,sunny_a相當於是該格式的名稱,可以自定義,但是調用的時候要一致
LogFormat"%{sunny_ip}i %l %u %t \"%r\" %>s %b\"%{Referer}i\" \"%{User-Agent}i\"" sunny_a
然後,調用該格式
CustomLog"logs/access_log" sunny_a
這樣就可以在服務器端的access_log裏監控到真實ip,而不是來自調度器的ip
.3、proxy_cache_path;
定義可用於proxy功能的緩存;Context:http,將資源的url經過hash運算後,得到128位的hash值,將得到的hash值進行緩存文件的分類緩存
語法如下
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number][manager_sleep=time] [manager_threshold=time][loader_files=number] [loader_sleep=time] [loader_threshold=time][purger=on|off] [purger_files=number] [purger_sleep=time][purger_threshold=time];
keys_zone這個很關鍵,設置緩存的名稱和內存的大小。這個名稱需要在server端裏調用
levels=levels是指將目錄分為幾級,用hash值的幾個數字作為第幾級的目錄
.4、proxy_cache
proxy_cache zone | off; 默認off
指明調用的緩存,或關閉緩存機制;Context:http, server, location
.5、proxy_cache_key
proxy_cache_key string;
緩存中用於“鍵”的內容
默認值:proxy_cache_key $scheme$proxy_host$request_uri;
.6、proxy_cache_valid
proxy_cache_valid [code ...] time;
定義對特定響應碼的響應內容的緩存時長,定義在http{...}中
示例:
proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m;
調用緩存功能,需要定義在相應的配置段,如server{...};
proxy_cache proxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 1h;
#將響應碼為200,302,301的數據才緩存,同時定義了時間1h
proxy_cache_valid any 1m;
.示例:
在http配置段裏定義緩存內容,使用時再分別調用
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2:2keys_zone=sunnyproxy:20m inactive=15s max_size=1g;
server 段中調用要寫key_zone裏定義的名稱
proxy_cache sunnyproxy; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 1h; proxy_cache_valid any 1m;
測試
在客戶端上訪問服務器的資源,如curl http://172.18.50.73/m.txt,然後在nginx上就會看到對應的目錄/var/cache/nginx/proxy_cache下就會生成一個hash後命名的文件,大小會比原來的大,因為緩存的數據是經過處理,會被封裝響應數據進去,所以緩存的數據會被源文件大一點
.7、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 ...
在被代理的後端服務器出現哪種情況下,可以直接使用過期的緩存響應客戶端
.8、proxy_cache_methods
proxy_cache_methods GET | HEAD | POST ...;
定義對哪些客戶端請求方法對應的響應進行緩存,GET和HEAD方法總是被緩存
.9、proxy_hide_header
proxy_hide_header field;
用於隱藏後端服務器特定的響應首部,默認情況下,nginx不會將代理服務器的響應中的頭字段“Date”,“Server”,“X-Pad”和“X-Accel -...”傳遞給客戶端。
.10、proxy_connect_timeout
proxy_connect_timeout time;
定義與後端服務器建立連接的超時時長,如超時會出現502錯誤,默認為60s,一般不建議超出75s,
.11、proxy_send_timeout
proxy_send_timeout time;
把請求發送給後端服務器的超時時長;默認為60s
.12、proxy_read_timeout
proxy_read_timeout time;
等待後端服務器發送響應報文的超時時長,默認為60s
本文出自 “陽光運維” 博客,請務必保留此出處http://ghbsunny.blog.51cto.com/7759574/1977250
Nginx 之 實現代理功能