1. 程式人生 > >分散式架構——Nginx 反向代理與負載均衡

分散式架構——Nginx 反向代理與負載均衡

訪問請移步至(David’s Wikipedia) https://www.qingdujun.com/ ,這裡有能“擊穿”平行宇宙的亂序並行位元組流…


原文地址:https://www.qingdujun.com/zh-CN/nginx-proxy-loadbalancing.html


本文介紹一下使用Nginx反向代理來做負載均衡。使用十分簡單,只需要配置upstream並選擇負載均衡策略,再配置server反向代理功能就全部搞定了。

架設Nginx服務

直接使用Docker啟動一臺虛擬Nginx伺服器。

$ sudo docker run --net=pub_net --ip=
192.168.1.13 --name macvlan_ngx1 --restart always -d nginx

配置Nginx服務——反向代理與負載均衡

Nginx的主配置檔案位於/etc/nginx/nginx.conf中。預設內容如下:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


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

    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;

    keepalive_timeout  65;

    #gzip  on;

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

可以很明顯的看到/etc/nginx/conf.d/*.conf中的所有.conf字尾的都會被自動載入作為配置檔案。為此,自定義配置檔案時,直接在conf.d目錄下新建字尾為.conf的檔案即可。

以下給出一份配置檔案,主要用於NginxTomcat轉發的負載均衡。我在Docker中虛擬出了5臺Tomcat伺服器(192.168.1.[19-23])

其中,由兩臺Tomcat伺服器組成了Web Server 1伺服器組(採用ip_hash演算法,就是根據ip做轉發)。用3臺Tomcat組成了Web Server 2伺服器組(設定伺服器轉發權重)。

upstream webserver1 {
    ip_hash;
    server 192.168.1.19:8080;
    server 192.168.1.20:8080;
}

upstream webserver2 {
    server 192.168.1.21:8080 weight=5;
    server 192.168.1.22:8080 weight=3;
    server 192.168.1.23:8080 weight=2;
}

server {
    listen 80;
    server_name tomcat1.com tomcat2.com;

    location / {
        proxy_pass http://webserver1;
    }
    location /hello {
        proxy_pass http://webserver1/hello;
    }
}

server {
    listen 80;
    server_name tomcat3.com tomcat4.com tomcat5.com;

    location / {
        proxy_pass http://webserver2;
    }
    location /world {
        proxy_pass http://webserver2/world;
    }
}

server {
    listen 80;
    server_name pc.com;

    location / {
		proxy_pass https://www.baidu.com/;
    }
}
一些注意事項

有幾點需要注意的,Nginx收到請求之後,會獲取請求的Host欄位,然後根據Host內容匹配server_name然後轉發給不同的server

轉發時直接使用proxy_pass指令即可,路徑中可以寫upstream以實現負載均衡。

下面摘錄了百度的一個請求內容。

GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/68.0.3440.84 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;
q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,ru;q=0.6
Cookie: //...

正因為這樣,我曾嘗試著在發起Http請求的時候動態設定Host欄位,但是一直沒成功(總是被總動糾正為當前的url)。後來查閱相關資料說是Http協議不讓設定Host欄位。

那麼,如何使用上Nginxserver_name機制?這裡一般就只能用DNS解析了,如果正式買了域名的話,比如baidu.com,會由域名註冊商提供DNS解析。

當然,這裡只是測試,可以直接修改本地的hosts檔案,設定域名和IP的對映關係,以達到DNS解析的效果。

配置hosts檔案

由於,這裡只啟動了一臺IP為192.168.1.13的Nginx伺服器,那麼在我的開發機(Windows 10,192.168.1.2)上的C:\Windows\System32\drivers\etc\hosts檔案中可以做以下對映。

192.168.1.13 tomcat1.com
192.168.1.13 tomcat2.com
192.168.1.13 tomcat3.com
192.168.1.13 tomcat4.com
192.168.1.13 tomcat5.com
192.168.1.13 pc.com
瀏覽器訪問Nginx伺服器

好了,測試Nginx配置檔案的有效性(這裡-t後不需要新增任何內容,不要寫成nginx -t /etc/nginx/nginx.conf):

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

重新載入Nginx

# nginx -s reload
2018/10/28 14:18:44 [notice] 24#24: signal process started

此時,就可以在開發機的瀏覽器中訪問Nginx伺服器,檢視具體的反向代理與負載均衡效果了:

http://tomcat1.com/
http://tomcat2.com/hello
http://tomcat3.com/world
http://pc.com/
©qingdujun
2018-11-27 北京 海淀

References:
[1] https://blog.csdn.net/wy757510722/article/details/75267431?utm_source=blogxgwz0
[2] https://blog.csdn.net/qq_21768483/article/details/78339450?utm_source=blogxgwz1
[3] https://www.w3cschool.cn/nginx/nginx-d1aw28wa.html
[4] https://blog.csdn.net/u012486840/article/details/52787282
[5] https://chrome.google.com/webstore/category/extensions?hl=zh-CN
[6] http://www.hangge.com/blog/cache/detail_1697.html
[7] https://www.telerik.com/fiddler
[8] https://blog.phpgao.com/nginx_config.html
[9] https://www.v2ex.com/t/305568
[10] https://js8.in/2011/10/29/檢查nginx配置,過載配置以及重啟的方法/