【第七課】Nginx反向代理和負載均衡

1、Nginx負載均衡集羣 介紹

  負載均衡(Load Balance)集羣提供了一種行之有效的辦法,來擴展網絡設備和服務器負載、帶寬和吞吐量,同時增強了網絡數據處理能力,提供了網絡的靈活性和可用性。html

  Nginx的負載均衡組件主要有2個:node

ngx_http_proxy_module:proxy代理模塊,用於把請求後端拋給服務器節點或upstream服務器池。nginx

ngx_http_upstream_module:負載均衡模塊,能夠實現網站的負載均衡功能和幾點的健康檢查。web

2、實現一個簡單的負載均衡

(1)環境介紹算法

站點訪問                    訪問主頁                    IP地址             角色
192.168.56.110:8081        welcome to bbs.abc.org        192.168.56.110        web1
192.168.56.111:8082        welcome to blog.abc.org       192.168.56.111        web2
www.abc.org                        無                     192.168.56.11        負載均衡

(2)配置bbs和blog站點並測試訪問vim

[root@localhost vhosts]# vim bbs.abc.org.conf 
server {
        listen 8081;
        server_name 192.168.56.110;
        root /vhosts/html/bbs;
        index index.html index.htm index.php;
}
[root@localhost vhosts]# vim blog.abc.org.conf
server {
        listen 8082;
        server_name 192.168.56.111;
        root /vhosts/html/blog;
        index index.html index.htm index.php;
}
[root@localhost vhosts]# curl 192.168.56.110:8081
welcome to bbs.abc.org
[root@localhost vhosts]# curl 192.168.56.111:8082
welcome to blog.abc.org

(3)配置負載均衡windows

[root@localhost vhosts]# cat www.abc.org.conf 
upstream web_server{      //配置負載均衡池
    server 192.168.56.110:8081 weight=1;
    server 192.168.56.111:8082 weight=1;
}
server {
    listen 80;
    server_name www.abc.org abc.org;
    root /vhosts/html/www;
    index index.html index.php index.htm;
    
    access_log logs/www.abc.org_access.log main;
    error_log logs/www.abc.org_error.log info;    
    
    location /{
        proxy_pass http://web_server;  //反向代理到負載均衡池
    }
    
    location ~ \.php$ {
            root           /vhosts/html/www;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }


}
[root@localhost vhosts]# nginx -t
nginx: the configuration file /usr/local/nginx1.15.1/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx1.15.1/conf/nginx.conf test is successful
[root@localhost vhosts]# nginx -s reload
[root@localhost vhosts]# curl www.abc.org  //測試訪問是否實現輪詢bbs和blog
welcome to bbs.abc.org
[root@localhost vhosts]# curl www.abc.org
welcome to blog.abc.org
[root@localhost vhosts]# curl www.abc.org
welcome to bbs.abc.org
[root@localhost vhosts]# curl www.abc.org
welcome to blog.abc.org

3、Nginx負載均衡組件介紹

一、upstream模塊後端

  Nginx的負載均衡功能依賴於ngx_http_upstream_module模塊,可支持代理的方式有:proxy_pass、fastcgi_pass、memcached_pass等。該模塊容許Nginx定義一組或多組節點服務器組,使用時,經過proxy_pass代理方式把網站的請求發送到實現定義好的upstream組的名稱上,具體的格式爲"proxy_pass http://web_server_pools",其中web_server_pools爲upstream節點服務器組名稱。下面舉例說明:緩存

upstream web_server{
    server 192.168.56.110:8081 weight=1 max_fails=1 fail_timeout=10s;
    server 192.168.56.111:8082 weight=1 max_fails=1 fail_timeout=10s;
   server 192.168.56.112:8083 weight=1 max_fails=1 fail_timeout=10s backup;
   server 192.168.56.113:8084 weight=1 max_fails=1 fail_timeout=10s down;
}

upstream參數說明:
server 192.168.56.110:8081  表示的是負載均衡後端的RS配置,能夠是IP或者域名,若是端口不寫,默認爲80端口,高併發場景下,IP能夠換成域名,經過DNS作負載均衡
weight=1  表明服務器的權重,默認爲1。權重數字越大表示接受的請求比例越大
max_fails=1  表示Nginx嘗試鏈接後端主機失敗的次數,這個值是配置proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream這3個參數使用,當Nginx接收後端服務器返回這3個參數定義的狀態碼時,會把這個請求轉發給正常工做的後端RS
fail_timeout=10s  在max_fails定義的的失敗次數後,距離下一次檢查的時間間隔,默認爲10s
backup  熱備配置(RS節點高可用)表示這個服務器做爲備份服務器,當主服務器所有宕機,就會向這個服務器轉發請求
down  表示該服務器永遠不可用,這個參數能夠配合ip_hash使用

二、upstream的調度算法

  調度算法通常分爲2類,一種是靜態調度算法,例如:rr、wrr、ip_hash等,負載均衡器根據自身設定的規則進行分配,不考慮後端節點服務器的狀況。

  一種是動態調度算法,例如least_conn、fair等,負載均衡器會根據後端節點服務器的當前狀態來決定是否分發請求。

  (1)rr輪詢(默認調度算法,靜態調度算法)

  按客戶端請求順序依次將客戶端的請求逐一分配到不一樣的後端服務器節點,和LVS的rr算法同樣,若是後端節點服務器宕機,宕機的服務器會從服務器池中剔除,保證用戶訪問的正常。

  (2)wrr(權重輪詢,靜態調度算法)

  在rr輪詢的基礎上增長權重,使用該算法時,權重和用戶訪問成比例,權重越大,請求數越多。

  (3)ip_hash(靜態調度算法)

  每一個請求按照客戶端的ip的hash結果分配,當新的請求到達,先將客戶端IP經過哈希算法哈希出一個值,在隨後的客戶端請求中,客戶的IP哈希值只要相同,就會被分配到同一臺服務器上。該調度算法能夠解決動態網頁的session共享問題,但也會致使請求分配不均勻。須要注意的是當負載均衡調度算法爲ip_hash時,後端服務器在負載均衡調度中的狀態不能使用weight和backup,即便配置了也不會生效。

  (4)fair(動態調度算法)

  該算法會根據後端服務器的響應時間來分配請求,響應時間較短的有限分配。這種算法更加的智能,能夠根據頁面大小和加載時長智能地進行負載均衡。Nginx自己不支持fair調度算法,若是須要使用這種算法,須要下載Nginx的相關模塊upstream_fair

  (5)least_conn

  該算法會根據後端節點的鏈接數來決定分配請求,哪一個機器的鏈接數少就優先分配。

  (6)url_hash算法

  根據訪問的URL的hash結果來分配請求,讓每一個URL定向到同一個後端服務器,後端服務器爲緩存服務器時效果顯著,能夠提升後端緩存服務器的命中率。Nginx自己不支持這種算法,須要安裝hash模塊軟件包。

三、http_proxy_module模塊和參數

  proxy_pass指令屬於ngx_http_proxy_module模塊,此模塊能夠將請求轉發到另外一臺服務器上,在實際的反向代理中,會經過location功能匹配指定的URI,而後把符合匹配規則的URI請求經過proxy_pass指向定義好的upstream池。

  http_proxy模塊的相關參數:

proxy_set_header    設置http請求header項傳給後端服務器節點,例如:能夠實現讓代理後端的服務器節點獲取訪問客戶端用戶的真是ip地址
client_body_buffer_size        用於指定客戶端請求主題緩衝區大小
proxy_connect_timeout        表示反向代理和後端節點服務器鏈接的超時時間,即發起三次握手等候響應的超時時間
proxy_send_timeout            表示代理後端服務器的數據回傳時間,即在規定時間內後端服務器必須傳完全部數據,不然,Nginx將會斷開鏈接
proxy_read_timeout            設置Nginx從代理的後端服務器獲取信息的時間,表示鏈接創建成功後,Nginx等待後端服務器的響應時間,實際上是Nginx已經進入了後端的排隊之中等待處理的時間
proxy_buffer_size            設置緩衝區大小,默認該緩衝區大小等於指令proxy_buffers設置的大小
proxy_buffers                設置緩衝區的數量和大小。Nginx從代理的後端服務器獲取的響應信息,會放置到緩衝區
proxy_busy_buffers_size        用於設置系統繁忙時期可使用的proxy_buffers大小,推薦大小爲proxy_buffers*2
proxy_temp_file_write_size    指定proxy緩存臨時文件的大小

舉個簡單的反向代理的例子:

[root@localhost vhosts]# !vim
vim www.abc.org.conf 
server {
        listen 80;
        server_name www.abc.org abc.org;
        root /vhosts/html/www;
        index index.html index.php index.htm;

        access_log logs/www.abc.org_access.log main;
        error_log logs/www.abc.org_error.log debug;
        location /bbs {    
                proxy_pass http://192.168.56.110:8081/;  //配置當訪問www.abc.org/bbs時,反向代理到192.168.56.110:8081這臺服務器上
        }

        location ~ \.php$ {
            root           /vhosts/html/www;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}
[root@localhost ~]# curl http://www.abc.org/bbs    //測試訪問
welcome to bbs.abc.org

4、Nginx負載均衡實際應用

一、環境說明

主機名 IP地址 角色說明
web01 192.168.56.12 nginx web01服務器
web02 192.168.56.13 nginx web02服務器
lb 192.168.56.11 nginx負載均衡器

二、Nginx反向代理負載均衡實踐

(1)在web01和web02上yum安裝nginx,並一樣修改nginx.conf

[root@web01 ~]# yum install -y nginx
[root@web02 ~]# yum install -y nginx
[root@web01 ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        server_name  bbs.abc.org;
        root         /application/html/bbs;
    index index.php index.html index.htm;
    }

    server {
    listen 80;
    server_name www.abc.org;
    root    /application/html/www;
    index index.php index.html index.htm;
    }
}

(2)配置web01和web02的host解析

[root@web01 ~]# cat /etc/hosts
192.168.56.12  bbs.abc.org www.abc.org
[root@web02 ~]# cat /etc/hosts
192.168.56.13  bbs.abc.org www.abc.org

(3)配置主頁index.html,並測試訪問

root@web01 ~]# mkdir /application/html/{www,bbs} -pv
[root@web01 ~]# echo "welcome to use bbs.abc.org 12" > /application/html/bbs/index.html
[root@web01 ~]# echo "welcome to use www.abc.org 12" > /application/html/www/index.html
[root@web02 ~]# mkdir /application/html/{www,bbs} -pv
[root@web02 ~]# echo "welcome to use bbs.abc.org 13" > /application/html/bbs/index.html
[root@web02 ~]# echo "welcome to use www.abc.org 13" > /application/html/www/index.html
[root@web01 ~]# curl www.abc.org
welcome to use www.abc.org 12
[root@web01 ~]# curl bbs.abc.org
welcome to use bbs.abc.org 12
[root@web02 ~]# curl www.abc.org
welcome to use www.abc.org 13
[root@web02 ~]# curl bbs.abc.org
welcome to use bbs.abc.org 13

(4)配置負載均衡器

[root@lb vhosts]# vim www.abc.org.conf 
upstream web_server{
        server 192.168.56.12:80 weight=1;
        server 192.168.56.13:80 weight=1;
}
server {
        listen 80;
        server_name www.abc.org abc.org;
        root /vhosts/html/www;
        index index.html index.php index.htm;

        access_log logs/www.abc.org_access.log main;
        error_log logs/www.abc.org_error.log debug;

        location /{
                proxy_pass http://web_server;
        }
}
[root@lb vhosts]# nginx -t
nginx: the configuration file /usr/local/nginx1.15.1/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx1.15.1/conf/nginx.conf test is successful
[root@lb vhosts]# nginx -s reload

(5)lb上綁定hosts解析,測試訪問

[root@localhost vhosts]# cat /etc/hosts
192.168.56.11 www.abc.org bbs.abc.org 
[root@lb vhosts]# curl www.abc.org
welcome to use bbs.abc.org 12
[root@lb vhosts]# curl www.abc.org
welcome to use bbs.abc.org 13

  從上面的測試結果能夠看到,正常地實現了反向代理和負載均衡,可是細緻地看一看,發如今訪問www.abc.org時,返回的的結果是welcome to use bbs.abc.org 12以及welcome to use bbs.abc.org 13,和咱們想要訪問到的結果:welcome to use www.abc.org 12以及welcome to use www.abc.org 13截然不同,徹底不一致!!這又是什麼緣由呢?

  在配置虛擬主機時,在web01和web02分別配置了2個虛擬主機,一個是bbs.abc.org,一個www.abc.org。bbs虛擬主機放在了前面,這點很重要。那麼當用戶訪問www.abc.org時,請求頭部攜帶了www.abc.org主機頭部請求Nginx的反向代理服務器,可是在反向代理服務器向後端服務器web01或web02從新發起請求時,默認並無在請求頭部信息告訴web01或web02要請求的是哪臺虛擬主機。因此,web服務器接收到請求後發現並無主機頭信息,所以web01或web02就直接將第一個虛擬主機(bbs.abc.org)發給了反向代理服務器了。

  那麼這問題又該如何解決呢?就是當反向代理向後端服務器發起請求時,要攜帶主機頭信息,以明確指明須要訪問的虛擬主機。具體配置也簡單,增長一行以下配置便可:

proxy_set_header Host $host;

  在代理向後端發送請求時,在http請求頭部加入了host字段信息後,若是後端配置了多個虛擬主機,它就能夠識別代理的是哪一個虛擬主機。從新配置後,訪問以下:

[root@localhost vhosts]# vim www.abc.org.conf 
upstream web_server{
        server 192.168.56.12:80 weight=1;
        server 192.168.56.13:80 weight=1;
}
server {
        listen 80;
        server_name www.abc.org abc.org;
        root /vhosts/html/www;
        index index.html index.php index.htm;

        access_log logs/www.abc.org_access.log main;
        error_log logs/www.abc.org_error.log debug;

        location /{
                proxy_set_header Host $host;
                proxy_pass http://web_server;
        }
}
[root@localhost vhosts]# nginx -t
nginx: the configuration file /usr/local/nginx1.15.1/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx1.15.1/conf/nginx.conf test is successful
[root@localhost vhosts]# nginx -s reload
[root@localhost vhosts]# curl www.abc.org
welcome to use www.abc.org 12
[root@localhost vhosts]# curl www.abc.org
welcome to use www.abc.org 13

  能夠看到最後的返回結果爲:welcome to use www.abc.org 12以及welcome to use www.abc.org 13,這就是proxy_set_header參數的做用。

三、反向代理後後端服務器記錄用戶真實IP

  在反向代理實現後,在windows客戶端作hosts解析,並訪問,在web01或web02上查看訪問日誌,以下:

[root@web01 ~]# cat /var/log/nginx/www.abc.org_access.log 
192.168.56.11 - - [20/Jul/2018:05:51:53 -0400] "GET / HTTP/1.0" 200 30 "-" "curl/7.29.0"
192.168.56.12 - - [20/Jul/2018:05:52:50 -0400] "GET / HTTP/1.1" 200 30 "-" "curl/7.29.0"
192.168.56.11 - - [20/Jul/2018:05:53:17 -0400] "GET / HTTP/1.0" 200 30 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"
192.168.56.11 - - [20/Jul/2018:05:53:40 -0400] "GET / HTTP/1.0" 200 30 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"

能夠看到對應的www.abc.org虛擬主機的訪問日誌記錄的並非客戶端ip,而是反向代理服務器的ip,那麼如何獲取用戶的真是ip呢?其實只須要增長如下參數便可:

proxy_set_header X-Forwarded-For $remote_addr;
表示在代理向後端服務器發送的http請求頭中加入X-Forwarded-For字段信息,用於後端服務器程序、日誌等接收記錄真實用戶的ip,而不是代理服務器的ip。在使用反向代理時,節點服務器獲取用戶真實ip的必要配置。
[root@localhost vhosts]# !vim  //修改負載均衡器的配置
vim www.abc.org.conf 
upstream web_server{
        server 192.168.56.12:80 weight=1;  //此處刪除了web02,做爲測試機訪問
}
server {
        listen 80;
        server_name www.abc.org abc.org;

        location /{
                proxy_pass http://web_server;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;  //配置記錄真實ip

        }
}
[root@web02 nginx]# curl www.abc.org  //在web02上配置hosts解析訪問www.abc.org 
welcome to use www.abc.org 12
[root@web01 ~]# tail -2 /var/log/nginx/www.abc.org_access.log
192.168.56.11 - - [20/Jul/2018:23:20:52 -0400] "GET / HTTP/1.0" 200 30 "-" "curl/7.29.0" "192.168.56.13"
192.168.56.11 - - [20/Jul/2018:23:21:45 -0400] "GET /index.html HTTP/1.0" 200 30 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36" "192.168.56.1"

配置完成後,重載訪問,查看web01上的日誌能夠看到,第一段表示的是$remote_addr,屬於代理服務器的ip,而最後一行纔是用戶的真是ip記錄。

相關文章
相關標籤/搜索