nginx的反向代理以及負載均衡模塊的使用

內容:html

一、何爲代理linux

二、nginx的反向代理模塊以及使用nginx

三、nginx的負載均衡模塊以及使用web


1、何爲代理正則表達式

代理,由字面意思能夠理解爲代爲服務的是意思。算法

代理服務技術是一門很古老的技術,是在互聯網早期出現就使用的技術。通常實現代理技術的方式就是在服務器上安裝代理服務軟件,讓其成爲一個代理服務器,從而實現代理技術。經常使用的代理技術分爲正向代理、反向代理。後端

正向代理:瀏覽器

正常的用戶訪問站點是客戶打開瀏覽器,而後輸入相關的網站進行瀏覽,其實這就是一個代理的行爲,只不過代理的是瀏覽器,咱們經過瀏覽器來代理請求站點服務,而正向代理服務器能夠理解爲:緩存

 wKioL1gTSg-SOQTFAAEt2yIdqGI777.png

反向代理:反向代理正好與正向代理相反,對於客戶端而言代理服務器就像是原始服務器,而且客戶端不須要進行任何特別的設置。客戶端向反向代理的命名空間(name-space)中的內容發送普通請求,接着反向代理將判斷向何處(原始服務器)轉交請求,並將得到的內容返回給客戶端。 bash

wKiom1gTSh-REsOzAAEbezfcntc760.png

因此,nginx因爲起輕量高效的特性,是的其成爲了反向代理服務器的熱門選擇。

2、ngixn的反向代理模塊以及使用

ngx_http_proxy_module模塊:

一、proxy_pass 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/;

二、proxy_set_header field value;設定發日後端主機的請求報文的請求首部的值;Context: http, server, location,經常使用於標記客戶端的真是IP地址

例:

proxy_set_header X-Real-IP  $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

三、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_

四、proxy_cache zone | off;

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

五、 proxy_cache_key string;

緩存中用於「鍵」的內容;

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

六、proxy_cache_valid [code ...] time;

定義對特定響應碼的響應內容的緩存時長;

定義在http{...}中;

proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g;

定義在須要調用緩存功能的配置段,例如server{...};

proxy_cache pxycache;

proxy_cache_key $request_uri;

proxy_cache_valid 200 302 301 1h;

proxy_cache_valid any 1m;

七、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 ...;

Determines in which cases a stale cached response can be used when an error occurs during communication with the proxied server.

八、proxy_cache_methods GET | HEAD | POST ...;

只有標記的相關請求方法才進行緩存

九、proxy_hide_header field;

By default, nginx does not pass the header fields 「Date」, 「Server」, 「X-Pad」, and 「X-Accel-...」 from the response of a proxied server to a client. The proxy_hide_header directive sets additional fields that will not be passed.

十、proxy_connect_timeout time;

Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.

默認爲60s;

ngx_http_headers_module模塊  

    向由代理服務器響應給客戶端的響應報文添加自定義首部,或修改指定首部的值;  

    一、add_header name value [always];

    添加自定義首部;

  例:

    add_header X-Via  $server_addr;

    add_header X-Accel $server_name;

   

    二、expires [modified] time;

    expires epoch | max | off;

    用於定義Expire或Cache-Control首部的值;

下面來進行操做效果的演示:

規劃:nginx反代的服務IP:10.1.249.75,後端真實服務器IP:10.1.252.235

在ngixn服務器中配置:

修改ngixn的反向代理服務中的配置文件,啓動反向代理模式

   location / {
        #root   /usr/share/nginx/html;
        proxy_pass http://10.1.252.235;
        index  index.html index.htm;
    }
[root@localhost upload]# ifconfig
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.249.75  netmask 255.255.0.0  broadcast 10.1.255.255
        inet6 fe80::20c:29ff:fe65:55a6  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:65:55:a6  txqueuelen 1000  (Ethernet)
        RX packets 9647  bytes 1463932 (1.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1736  bytes 231308 (225.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


在真實服務器中提供測試頁面:

[root@localhost html]# cat index.html 
RS1


在客戶端測試,已經成功訪問只後端服務器

[root@localhost ~]# curl 10.1.249.75
RS1
[root@localhost ~]# curl 10.1.249.75
RS1


查看真實服務器的訪問日誌,發現訪問的客戶段IP是代理服務器的IP:

[root@localhost html]# tail /var/log/httpd/access_log 
10.1.249.75 - - [28/Oct/2016:20:10:46 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:46 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:46 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:49 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"


有沒有辦法獲取真正的客戶端IP呢?答案是確定的,nginx提供了自身的變量能夠提取原始客戶的請求報文信息,只須要保留原客戶端的真實IP便可

修改nginx的配置文件,添加其中一條命令:proxy_set_header X-Real-IP $remote_addr;

   

location / {
        #root   /usr/share/nginx/html;
        proxy_pass http://10.1.252.235;
        proxy_set_header X-Real-IP $remote_addr;
        index  index.html index.htm;
    }
[root@localhost upload]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost upload]# nginx -s reload

            再次測試,並訪問日誌:

[root@localhost html]# tail /var/log/httpd/access_log 
10.1.249.75 - - [28/Oct/2016:20:10:46 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:49 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:16:01 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:16:04 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"


發現源IP仍是沒有變,這是由於httpd的配置文件定義了日誌的格式,只須要簡單修改日誌格式便可,講%h改成以前nginx定義的報文首部{X-Real-IP}i

LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined


再次測試,並訪問日誌,已經能正確記錄遠端客戶的IP了!

[root@localhost html]# !tai
tail /var/log/httpd/access_log 
10.1.249.75 - - [28/Oct/2016:20:10:47 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:48 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:10:49 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:16:01 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.249.75 - - [28/Oct/2016:20:16:04 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.252.215 - - [28/Oct/2016:20:19:40 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.252.215 - - [28/Oct/2016:20:19:40 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.1.252.215 - - [28/Oct/2016:20:19:41 +0800] "GET / HTTP/1.0" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"


3、nginx的負載均衡模塊以及使用

與lvs不一樣的是,nginx在應用層提供了強大的負載均衡的功能,並帶有後端服務的健康檢查功能。

nginx的負載均衡模塊怎麼使用?

ngx_http_upstream_module模塊 (定義在http上下文)

一、upstream name { ... }

定義後端服務器組,會引入一個新的上下文;Context: http

upstream httpdsrvs {

server ...

server...

...

}

二、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

設置將服務器標記爲不可用狀態的超時時長;

max_conns

當前的服務器的最大併發鏈接數;

backup

將服務器標記爲「備用」,即全部服務器均不可用時此服務器才啓用;

down

標記爲「不可用」;

三、least_conn;

最少鏈接調度算法,當server擁有不一樣的權重時其爲wlc;

四、 ip_hash;

源地址hash調度方法;

五、hash key [consistent];

基於指定的key的hash表來實現對請求的調度,此處的key能夠直接文本、變量或兩者的組合;

做用:將請求分類,同一類請求將發往同一個upstream server;

示例:

hash $request_uri consistent;

hash $remote_addr;

六、keepalive connections;

爲每一個worker進程保留的空閒的長鏈接數量;

下面來實驗驗證:

規劃:nginx反代的服務IP:10.1.249.75,後端服務器RS1:10.1.252.235,後端服務器RS2:10.1.252.215

(1)RS1,RS2啓動web服務,並提供相關的測試頁面

(2)配置nginx的負載均衡:

在httpd段添加:

   

upstream test {
    server 10.1.252.235;
    server 10.1.252.215;
}

(3)啓動反向代理模式,並實現負載均衡:

   

location / {
        #root   /usr/share/nginx/html;
        proxy_pass http://test;
        proxy_set_header X-Real-IP $remote_addr;
        index  index.html index.htm;
    }
[root@localhost upload]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost upload]# nginx -s reload

(4)客戶端測試,已經能夠實現負載均衡功能(默認是輪詢rr算法):

[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS2
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS2
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS2
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS2


(5)添加權重測試:

 

  upstream test {
    server 10.1.252.235 weight=2;
    server 10.1.252.215;
}
[root@localhost ~]# curl http://10.1.249.75
RS2
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS2
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS2
[root@localhost ~]# curl http://10.1.249.75
RS1
[root@localhost ~]# curl http://10.1.249.75
RS1

(6)咱們知道,lvs的負載均衡調度中,lvs自身並無對後端服務器進行健康狀態檢測的機制,也就是說後端服務器掛了仍是會照樣進行調度,而ngixn則進行健康狀態檢查。修改配置以下:

 

  upstream test {
    server 10.1.252.235 max_fails=3 fail_timeout=10;
    server 10.1.252.215 max_fails=3 fail_timeout=10;
}

        (7)停掉RS1前的測試:

[root@localhost ~]# for i in `seq 10`;do curl http://10.1.249.75;done 
RS1
RS2
RS1
RS2
RS1
RS2
RS1
RS2
RS1
RS2

        (8)停掉RS1測試:

[root@localhost html]# service httpd stop
Stopping httpd:                                            [  OK  ]
[root@localhost html]# 
[root@localhost ~]# for i in `seq 10`;do curl http://10.1.249.75;done 
RS2
RS2
RS2
RS2
RS2
RS2
RS2
RS2
RS2
RS2

(9)已經自動把RS排除,如今再次恢復RS測試:

[root@localhost ~]# for i in `seq 10`;do curl http://10.1.249.75;done 
RS2
RS1
RS2
RS1
RS2
RS1
RS2
RS1
RS2
RS1


        好了nginx的反向代理和負載均衡功能就演示到這裏,更多文章請關注 個人博客

相關文章
相關標籤/搜索