配置Nginx作為反向代理服務器
一、nginx作為反向代理的工作模型:
1、nginx作為反向代理的工作模型
nginx工作在應用層,其能理解并可以提取出http請求報文中的首部信息中的請求方法、url、http協議版本等信息。
nginx反向服務器接收到請求報文之后,會啟動一個請求連接,把用戶的請求重新封裝為一個請求報文,由nginx反向服務器作為客戶端向Real Server進行請求。
此時,nginx反向代理服務器中封裝的首部信息可能與接受到的客戶端的首部信息不完全一致,這取決于其與RS(Real Serve)協商的結果。
nginx作為反向代理其功能類似于DNAT所實現的功能,能夠實現隱藏真實服務器的目的。
2、nginx也具有緩存功能
nginx作為反向代理服務器也具有緩存功能,但其首先是反向代理服務器,之后才是緩存服務器。
反帶和緩存是兩個不同的功能。
透傳式代理才具有緩存功能:
來自于客戶端的請求,若在Nginx Server上沒有相應的內容,Nginx Server要負責向Real Server發起請求獲取內容。對于Client來說,Real Server是不可見的。
旁路式緩存/旁掛式緩存:
Client直接向緩存服務器請求,緩存服務器沒有相應的內容,Client要想Real Server發起請求,由Real Server響應。
Nginx作為http服務器的緩存時,只對get、head等讀請求方法作緩存查詢。
Nginx查找緩存時,若沒有命中緩存,會產生額外的開銷,因此,提升緩存命中率是必要的。根據LRU(最近最少算法)清理緩存。緩存有效期,確保緩存的內容與原服務器的內容一致,有效期到達之后,緩存服務器發送條件式請求,詢問原服務器資源是否發生改變,若沒有發生改變,則不會清理。
X-Forwarded-for用來解決在RS上無法分析到真實客戶端的請求IP的問題,反帶服務器在接受到客戶端的請求時,會檢查請求報文中的首部信息,若其不存在X-Forwarded-for信息,則其將Client的真實IP信息記錄于其中,若已存在,則不再另行封裝,之后,再將報文發給RS,在RS上即可查看到Client的IP信息。
二、Nginx作為反向代理的實現
通過ngx_http_proxy_module模塊來實現反向代理的功能
1、proxy_pass URL;指定代理至后端服務器的URL
Context位置:location, if in location, limit_except
注意:
1)proxy_pass后面的路徑不帶uri時,其會將location的uri傳遞給后端主機;
server {
…
server_name HOSTNAME;
location /uri/ {
proxy http://hos[:port];
}
…
}
http://HOSTNAME/uri –> http://host/uri
2)proxy_pass后面的路徑是一個uri時,其會將location的uri替換為proxy_pass的uri;
server {
…
server_name HOSTNAME;
location /uri/ {
proxy http://host/new_uri/;
}
…
}
http://HOSTNAME/uri/ –> http://host/new_uri/
3)如果location定義其uri時使用了正則表達式的模式,則proxy_pass之后必須不能使用uri; 用戶請求時傳遞的uri將直接附加代理到的服務的之后;
server {
…
server_name HOSTNAME;
location ~|~* /uri/ {
proxy http://host;
}
…
}
http://HOSTNAME/uri/ –> http://host/uri/;
配置示例1:
實驗環境:
nginx proxy server:centos7 192.168.154.130
webserver1:centos6.8 192.168.154.128
webserver2:centos6.8 192.168.154.129
目的:1)實現訪問192.168.154.130其頁面為192.168.154.129提供的頁面
2)實現訪問192.168.154.130/wordpress其頁面為192.168.154.128提供的頁面
3)實現訪問192.168.154.130/wordpress其頁面為192.168.154.128/wordpress提供的頁面。注意第2和第三配置實現的區別
192.168.154.128提供的頁面內容為:
192.168.154.128/wordpress提供的頁面內容為:
192.168.154.129提供的頁面內容為:
配置步驟
1)
a)、在nginx server上安裝nginx,過程略
b)、配置nginx.conf文件,在對應的server上下文中配置:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
proxy_pass http://192.168.154.129;
index index.html index.htm;
}
注意:若root與proxy_pass配置同時出現,則proxy_pass生效。也可以注釋掉root
c)測試配置文件是否有誤
nginx -t
d)啟動nginx或重新加載配置文件
nginx 或 nginx -s reload
e)在webserver上安裝httpd,配置測試站點,啟動httpd服務。
f)通過訪問nginx proxy server,測試反帶配置是否成功
2)當proxy_pass http://192.168.154.128;后帶uri時
其會將location后的/wordpress/替換為proxy_pass http://192.168.154.128后的uri,即傳遞給后端RealServer的url為http://192.168.154.128/,其請求獲取的資源為192.168.154.128/提供的頁面內容
3)當proxy_pass http://192.168.154.128;后不帶uri時
其會將location后的/wordpress/補在proxy_pass http://192.168.154.128后,即傳遞給后端RealServer的url為http://192.168.154.128/wordpress。其請求獲取的資源為192.168.154.128/wordpress提供的頁面內容
配置示例2:
實現訪問任何圖片資源,其請求的內容都是由192.168.154.128提供的圖片資源,配置如下:
location ~* \.(jpg|img|jpeg|png)$ {
proxy_pass http://192.168.154.128;
}
要能成功訪問,請求的資源必選已經存在于192.168.154.128服務器上。
測試訪問:http://192.168.154.130/1.jpg
測試訪問:http://192.168.154.130/imgs/test2.jpg
配置示例2:
實現將php頁面的訪問請求都提交給192.168.154.128
location ~* \.php$ {
proxy_pass http://192.168.154.128;
}
在192.168.154.128上要安裝配置好php,之后測試
三、如何解決Real Server后端記錄的日志IP為反帶服務器的IP,而不是真正的Client的IP。
proxy_set_header field value;
設定發往后端主機的請求報文的請求首部的值;
Context位置:http, server, location
1、Client與Real Server之間的請求只經過一次反帶。
直接在發往后端主機的請求報文首部中設定Client的IP。
proxy_set_header X-Real-IP $remote_addr;
2、Client與Real Server之間的請求經過多級反帶。
此時,如果直接直接在發往后端主機的請求報文首部中設定Client的IP。
在經過多級代理之后,其記錄的IP為最后一級代理服務器的上一級代理的IP,并不是真正的Client的IP。真正的Client IP被記錄在$proxy_add_x_forwarded_for變量中,只需向后端Real Server傳遞此變量即可。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
配置步驟:
1)編輯nginx.conf文件,在需要記錄日志的相應上下文加上
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2)在后端Real Server上配置
變價httpd.conf配置文件,修改LogFormat配置,將反帶服務器傳遞的參數替代%h
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
在后端Real Server上追蹤httpd訪問日志,
四、定義和啟用nginx的緩存機制
1、proxy_cache_path
定義可用于proxy功能的緩存;
Context位置:http
用法:
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];
2、proxy_cache zone | off;
指明要調用的緩存,或關閉緩存機制;
Context位置:http, server, location
3、 proxy_cache_key string;
緩存中用于“鍵”的內容;
默認值:proxy_cache_key $scheme$proxy_host$request_uri;
注意:1)當緩存服務器要同時支持http及https,使用$scheme會造成http和https不能共享緩存。
2)當后端RS不止一臺服務器時,使用$proxy_host,被調度后也不能共享緩存
因此,可以顯示指定僅使用$request_uri為緩存中的"鍵"。
4、proxy_cache_valid [code …] time;
定義對特定響應碼的響應內容的緩存時長;
定義在需要調用緩存功能的配置段,例如server{…}或location{…};
配置示例:
緩存圖片資源。
1)定義緩存
proxy_cache_path只能定義在http{…}中;
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g;
2)調用緩存
3)創建緩存目錄,mkdir -pv /var/cache/nginx/proxy_cache
4)測試配置是否有誤
5)重載配置
之后,請求http://192.168.154.130/1.jpg,查看緩存是否命中。
緩存相關的優化配置:
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 …;
當代理服務器與后端主機通信出現故障時,在哪種情況下可以使用緩存中的緩存項響應給客戶端。此緩存項內容可能過期。
error、timeout、invalid_header…表示通信故障描述,即當代理服務器與后端RS通信故障原因為指定的短語時,使用緩存內容響應給客戶端。
off表示不使用過期內容響應給客戶端
6、proxy_connect_timeout time
定義代理與后端RS的連接超時時長,默認為60秒,最大不能超過75秒。
7、proxy_cache_methods GET | HEAD | POST …;
定義為哪些請求方法是用緩存。建議僅對GET、HEAD方法是用緩存,默認也為GET、HEAD方法。
五、對后端服務器響應報文的header的處理
1、proxy_hide_header field
指明要隱藏的后端服務器響應報文的header,默認情況下,不會傳遞“Date”, “Server”, “X-Pad”, and “X-Accel-…”header的信息。此定義能夠避免后端服務器信息被泄露。
2、使用ngx_http_headers_module模塊,可以實現由代理服務器響應給客戶端的響應報文中添加自定義首部,或,修改指定首部的值。
2.1 、add_header name value [always];添加自定義首部;
Context位置:http, server, location, if in location
add_header X-Via $server_addr;告知客戶端其請求是由誰代理
add_header X-Accel $server_name;告知客戶端其請求由誰給予加速
2.2、expires [modified] time;用于定義Expire的值,其應用場景為,假若在反帶服務器上,設定緩存在1小時之后過期,但經過判定,該內容長期不會改變,此時,修改expires的值
expires epoch | max | off; 用于修改Cache-Control首部的值;
Context位置:http, server, location, if in location
示例:在nginx上增加X-via、X-Accel響應頭部
之后,測試配置是否有誤,重新加載配置。
在客戶端通過瀏覽器查看器響應頭部,可以查看到增加的頭部信息
六、Nginx反帶實現負載均衡
通過ngx_http_upstream_module模塊來定義后端服務器組,在后端服務器組中能夠實現負載均衡調度。
Nginx作為反帶時支持對后端服務器的監控狀態做檢測,當其檢測到無法與某后端服務器建立連接時,其不會再將請求調度至該服務器。
在使用負載均衡功能時,Nginx反帶服務器和各Real Server之間的時間必須要同步。
1、upstream name { … },定義后端服務器組,會引入一個新的上下文;
Context位置:http
用法:
upstream httpdsrvs {
server …
server…
…
}
2、server address [parameters];在upstream上下文中server成員,以及相關的參數;
Context位置:upstream
address的表示格式:
unix:/PATH/TO/SOME_SOCK_FILE
IP[:PORT]
HOSTNAME[:PORT]
parameters可用的參數有:
weight=number 權重,默認為1;
max_fails=number 失敗嘗試最大次數;超出此處指定的次數時,server將被標記為不可用;
fail_timeout=time 設置將服務器標記為不可用狀態的超時時長,默認為10秒;
max_conns 當前的服務器的最大并發連接數;
backup將服務器標記為“備用”,即所有服務器均不可用時此服務器才啟用;
down 將服務器標記為“不可用”;
配置示例:
實驗環境:
nginx proxy server:centos7 192.168.154.130
webserver1:centos6.8 192.168.154.128
webserver2:centos6.8 192.168.154.129
實驗1:實現將對nginx server的請求負載均衡調度至webserver1、webserver2,為了以示區別,webserver1、webserver2提供不同的頁面內容。
webserver1提供的頁面內容為:
webserver2提供的頁面內容為:
配置步驟
1)在nginx.conf中定義名為webcluster的upstream
注意,server不能指定協議,在引用時指定即可
2)在要實現負載的server上下文或location上下文中定義proxy_pass,引用定義好的upstream即可。
3)測試配置是否有誤,之后重載配置
4)測試。
默認情況下,負載均衡使用的算法為RR(Round Robin)算法。
實驗2:根據服務器負載能力,將對nginx server的請求按負載調度至webserver1、webserver2,假設webserver1負載能力為2,webserver2負載能力為1。
配置如下:
1)在upstream中的server后指定權重即可。
默認情況下,權重的值為1,可不用特別指定。
2)測試配置是否有誤,之后重載配置
3)測試。
3、least_conn; 我們知道nginx進行調度時,期默認算法為輪詢算法,輪詢算法是把請求平均的轉發給各個后端,使它們的負載大致相同。這有個前提,就是每個請求所占用的后端時間要差不多,如果有些請求占用的時間很長,會導致其所在的后端負載較高。在這種場景下,把請求轉發給連接數較少的后端,能夠達到更好的負載均衡效果,這就是least_conn算法。
least_conn首先遍歷后端集群,比較每個后端的conns/weight,選取該值最小的后端。如果有多個后端的conns/weight值同為最小的,那么對它們采用加權輪詢算法。。
4、 ip_hash; 源地址hash調度方法;基于Client的IP做調度。將來至于同一個IP地址的請求分發給同一個后端服務器。
配置示例:
檢查并重載配置
測試
5、hash key [consistent] ; 基于指定的key的hash表來實現對請求的調度,此處的key可以直接文本、變量或二者的組合;
作用:將請求分類,同一類請求將發往同一個upstream server;
consistent,使用一致性hash算法,其意義在于,當某臺RS出現故障時,能夠降低影響到的掉讀請求的范圍。
示例:
hash $request_uri consistent;同一個uri請求將會被分發至相同的RS上。
hash $remote_addr; 同一個IP地址的請求將會被分發至相同的RS上,類似于ip_hash。
hash $cookie_name;來至于同一個瀏覽器的請求將會 被分發至相同的RS上。
6、keepalive connections; 為每個worker進程保留的空閑的長連接數量;
在nginx上沒有啟用緩存時,來至于客戶端的請求都會被調度至后端服務器,當請求數較大時,如果使用短鏈接,會消耗掉大量的Nginx反帶服務器上的端口,為了避免出現此情況,在Nginx與RS連接時,可以使用長連接。
七、使用Nginx反帶、分發tcp或udp協議
基于ngx_stream_core_module來實現此功能。此時Nginx工作與傳輸層。
1、stream { … } 定義stream相關的服務;
Context位置:main
stram上下文與http上下文為平級關系,在stream上下文中,也可以使用http中的方法來定義。
stream {
upstream name {
server ip[:port];
server ip[:port];
…
}
server {
listen ip[:port]; 定義通過哪個ip及port來接受請求
proxy_pass sshsrvs; 此處的proxy_pass不可指定協議,只需將其請求調度至后端服務器即可。
}
}
2、listen
listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
配置示例:
在webserver1、webserver2分別配置mysql服務,以mysqlserver1、mysqlserver2加以區別。通過192.168.154.130:33106來實現對后端mysql服務請求的負載均衡調度。
為了能夠明晰測試,在mysqlserver1、mysqlserver2分別創建名為server1、server2的database,且授權同一個用戶能夠在遠程訪問。此配置不再贅述。
配置stream步驟:
1)編輯nginx.conf文件,增加一下內容
注意其上下文位置需與http同級。
2)測試配置是否有誤,之后重載配置
3)查看33106端口是否監聽
4)在遠端主機上進行測試
for i in {1..10};do mysql -ucluster -h192.168.154.130 -P 33106 -pcluster -e "show databases;"; done
原創文章,作者:M20-1鐘明波,如若轉載,請注明出處:http://www.www58058.com/55565