前言
- 本文章的目的旨在使用Nginx解決高并發情況下的負載均衡問題,也就是通常我們所說的叢集。
讀前準備
- 本文章涉及nginx的一些知識内容,以及正向代理和反向代理的概念了解,這些知識可參考我的部落格裡Nginx分類子產品的内容。
- 我的部落格關于nginx的内容位址為:https://blog.csdn.net/zengwende/article/category/8635956
解決問題
當通路量劇增的時候,單個伺服器已經無法滿足要求,此時應該要多個伺服器一起分擔壓力,需要實作負載均衡請求分發(叢集)
實驗環境
1、三個不同端口的Tomcat(我三個tomcat的端口分别是8080、8081、8082)
2、Nginx(我的nginx版本為1.14.2)
解決方案
注:所有的代碼修改都在nginx的nginx.conf檔案上,192.168.3.38設定為我的本地IP
1、輪詢(預設方式)
每個請求按時間順序逐一配置設定到不同的後端伺服器,如果後端伺服器挂掉,能自動剔除,指定輪詢幾率,weight和通路比率成正比,用于後端伺服器性能不均的情況。(如果不配權重weight,那就是按照順序配置設定,相當于配置的weight都等于1)
#關鍵的代碼
upstream zengwd.com {
server 192.168.3.38:8080 weight=1 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8081 weight=2 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8082 weight=2 max_fails=2 fail_timeout=2s;
}
server {
listen 80;
server_name 192.168.3.38;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://zengwd.com;
proxy_redirect default;
proxy_connect_timeout 2s;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
拓展:
這個等待響應的時間我們是可以配置的。
這個時間由以下3個參數控制:
proxy_connect_timeout:與伺服器連接配接的逾時時間,預設60s
fail_timeout:當該時間内伺服器沒響應,則認為伺服器失效,預設10s
max_fails:允許連接配接失敗次數,預設為1
實驗步驟
1、通路192.168.3.38(為什麼通路這個位址?因為我們nginx的虛拟主機的server_name已經配置了192.168.3.38,相當于nginx已經代理了192.168.3.38,而我們通路192.168.3.38相當于通路192.168.3.38的80端口,nginx的預設端口也是80,是以通路192.168.3.38位址,就會通過nginx的代理)
2、觀察現象(連續通路5次)
實驗結果
第一次通路
第二次通路
第三次通路
第四次通路
第五次通路
從上面簡單地實驗現象我們可以看出通路8080、8081、8082的比例為1:2:2,這跟我們配置的輪詢的權重政策一緻,是以,在輪詢的政策中,權重值越高,通路的機率越高,且按照配置設定的權重的比例來輪詢。
2、ip_hash
每個請求按通路ip的hash結果配置設定,這樣每個訪客固定通路一個後端伺服器,可以解決session的問題。
#關鍵的代碼
upstream zengwd.com{
ip_hash;
server 192.168.3.38:8080 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8081 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8082 max_fails=2 fail_timeout=2s;
}
server {
listen 80;
server_name 192.168.3.38;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://zengwd.com;
proxy_redirect default;
proxy_connect_timeout 2s;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
實驗步驟
1、通路192.168.3.38
2、觀察現象(連續通路5次)
實驗結果
第一次通路
第二次通路
第三次通路
第四次通路
第五次通路
從上面簡單地實驗現象我們可以看出無論我怎麼通路我就隻能通路到tomcat1,也就是8080端口,因為nginx的ip_hash政策就是一個IP固定隻能通路同一台伺服器,與輪詢不同。
3、最少連接配接
把請求配置設定到連接配接數最少的server,這樣使得伺服器之間的壓力差不會過大。
#關鍵的代碼
upstream zengwd.com{
least_conn;
server 192.168.3.38:8080 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8081 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8082 max_fails=2 fail_timeout=2s;
}
server {
listen 80;
server_name 192.168.3.38;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://zengwd.com;
proxy_redirect default;
proxy_connect_timeout 2s;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
實驗就不做了,步驟都是大同小異。最小連接配接這樣的政策方式能夠平均伺服器的壓力,不會出現有的負荷過重,有的幾乎無壓力的情況。
4、fair(第三方)
按後端伺服器的響應時間來配置設定請求,響應時間短的優先配置設定。這個需要安裝第三方的插件,如果有需要的我出安裝fair教程,請在評論區下留言。
#關鍵的代碼
upstream zengwd.com{
server 192.168.3.38:8080 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8081 max_fails=2 fail_timeout=2s;
server 192.168.3.38:8082 max_fails=2 fail_timeout=2s;
fair;
}
server {
listen 80;
server_name 192.168.3.38;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://zengwd.com;
proxy_redirect default;
proxy_connect_timeout 2s;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
結語
大家可以根據自己伺服器的狀況自由搭配配置設定政策,以上的政策基本上能夠滿足叢集的需求。其實還有一個問題,以上的問題都是解決伺服器的壓力問題,這都是建立在nginx的伺服器沒有挂掉的情況。如果nginx伺服器挂掉了,等于整個系統都挂掉了,是以這是不是要考慮nginx的叢集?還是其他措施?可關注我後續的文章,有興趣的請留言。
彩蛋
nginx的conf檔案最好不要出現Tab等特殊字元或者隐藏字元,否則很容易報錯。當然具體的原因可以看下nginx下的logs的error日志。