1. 程式人生 > >Nginx 之 實現代理功能

Nginx 之 實現代理功能

proxy nginx

1 概述


ngx_http_proxy_module模塊允許將請求傳遞給另一個服務器,也可以充當應用級的反向代理。根據應用進行調度。訪問的時候,服務器認為是代理服務器訪問的,如果要看真實的訪問者,需要到代理服務器上的log去訪問.這個可以通過proxy_set_header這個命令進行配置,使得在提供服務的服務器器上查看到真實的客戶端ip.


2 配置介紹


1proxy_pass

proxy_pass URL;

Context:location, if in location,limit_except

註意:proxy_pass後面的路徑不帶uri時,其會將locationuri傳遞給後端主機

server { 
...
server_name  HOSTNAME;
location  /uri/  {
proxy_pass http://host[:port]; #最後沒有/
}
...
}

上面示例:http://HOSTNAME/uri--> http://host/uri

.proxy_pass後面的路徑是一個uri時,其會將locationuri替換為proxy_passuri

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後面加了

/斜線,意思是訪問curl 172.18.50.73/fujian 相當於是訪問了 http://192.168.25.108/,相當於是對url做了置換

例子:

 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時使用了正則表達式的模式,則

proxy_pass之後必須不能使用uri; 用戶請求時傳遞的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.txt172.18.50.73這臺服務器在家目錄下可以沒有m.txt,但是,在服務器172.18.50.75這臺的主目錄下要有m.txt,否則無法訪問,因為實際會調度到後端的http://172.18.50.75/m.txt這個資源。

.2proxy_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

.3proxy_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值的幾個數字作為第幾級的目錄

.4proxy_cache

proxy_cache zone | off; 默認off

指明調用的緩存,或關閉緩存機制;Context:http, server, location

.5proxy_cache_key

proxy_cache_key string;

緩存中用於的內容

默認值:proxy_cache_key $scheme$proxy_host$request_uri;

.6proxy_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後命名的文件,大小會比原來的大,因為緩存的數據是經過處理,會被封裝響應數據進去,所以緩存的數據會被源文件大一點

.7proxy_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 ...

在被代理的後端服務器出現哪種情況下,可以直接使用過期的緩存響應客戶端

.8proxy_cache_methods

proxy_cache_methods GET | HEAD | POST ...;

定義對哪些客戶端請求方法對應的響應進行緩存,GETHEAD方法總是被緩存

.9proxy_hide_header

proxy_hide_header field;

用於隱藏後端服務器特定的響應首部,默認情況下,nginx不會將代理服務器的響應中的頭字段“Date”“Server”“X-Pad”“X-Accel -...”傳遞給客戶端。

.10proxy_connect_timeout

proxy_connect_timeout time;

定義與後端服務器建立連接的超時時長,如超時會出現502錯誤,默認為60s,一般不建議超出75s

.11proxy_send_timeout

proxy_send_timeout time;

把請求發送給後端服務器的超時時長;默認為60s

.12proxy_read_timeout

proxy_read_timeout time;

等待後端服務器發送響應報文的超時時長,默認為60s



本文出自 “陽光運維” 博客,請務必保留此出處http://ghbsunny.blog.51cto.com/7759574/1977250

Nginx 之 實現代理功能