Nginx負(fù)載均衡
1、負(fù)載均衡的作用
如果你的nginx服務(wù)器給2臺(tái)web服務(wù)器做代理,負(fù)載均衡算法采用輪詢,那么當(dāng)你的一臺(tái)機(jī)器web程序關(guān)閉造成web不能訪問,那么nginx服務(wù)器分發(fā)請(qǐng)求還是會(huì)給這臺(tái)不能訪問的web服務(wù)器,如果這里的響應(yīng)連接時(shí)間過長,就會(huì)導(dǎo)致客戶端的頁面一直在等待響應(yīng),對(duì)用戶來說體驗(yàn)就打打折扣,這里我們?cè)趺幢苊膺@樣的情況發(fā)生呢。這里我配張圖來說明下問題。

如果負(fù)載均衡中其中web2發(fā)生這樣的情況,nginx首先會(huì)去web1請(qǐng)求,但是nginx在配置不當(dāng)?shù)那闆r下會(huì)繼續(xù)分發(fā)請(qǐng)求到web2,然后等待web2響應(yīng),直到我們的響應(yīng)時(shí)間超時(shí),才會(huì)把請(qǐng)求重新分發(fā)給web1,這里的響應(yīng)時(shí)間如果過長,用戶等待的時(shí)間就會(huì)越長。
2、upstream配置
首先給大家說下 upstream 這個(gè)配置的,這個(gè)配置是寫一組被代理的服務(wù)器地址,然后配置負(fù)載均衡的算法。這里的被代理服務(wù)器地址有2種寫法。
upstream youngfitapp {
? ?? server 192.168.62.157:8080;
? ?? server 192.168.62.158:8080;
?? }
server {
? ? ?? listen 80;
? ? ?? server_name localhost;
? ? ?? location / { ? ? ? ?
? ? ? ? ? proxy_pass? http://youngfitapp;
? ? ?? }
}
3、負(fù)載均衡算法
upstream 支持4種負(fù)載均衡調(diào)度算法:
A、輪詢(默認(rèn)):每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器;
B、ip_hash:每個(gè)請(qǐng)求按訪問IP的hash結(jié)果分配,同一個(gè)IP客戶端固定訪問一個(gè)后端服務(wù)器??梢员WC來自同一ip的請(qǐng)求被打到固定的機(jī)器上,可以解決session問題。
C、url_hash:按訪問url的hash結(jié)果來分配請(qǐng)求,使每個(gè)url定向到同一個(gè)后端服務(wù)器。后臺(tái)服務(wù)器為緩存的時(shí)候效率。
D、fair:這是比上面兩個(gè)更加智能的負(fù)載均衡算法。此種算法可以依據(jù)頁面大小和加載時(shí)間長短智能地進(jìn)行負(fù)載均衡,也就是根據(jù)后端服務(wù)器的響應(yīng)時(shí)間來分配請(qǐng)求,響應(yīng)時(shí)間短的優(yōu)先分配。Nginx本身是不支持 fair的,如果需要使用這種調(diào)度算法,必須下載Nginx的 upstream_fair模塊。
3、配置實(shí)例
1、熱備:如果你有2臺(tái)服務(wù)器,當(dāng)一臺(tái)服務(wù)器發(fā)生事故時(shí),才啟用第二臺(tái)服務(wù)器給提供服務(wù)。服務(wù)器處理請(qǐng)求的順序:AAAAAA突然A掛啦,BBBBBBBBBBBBBB.....
upstream myweb {
server192.168.62.157:8080;
server192.168.62.158:8080 backup;#熱備 ? ?
?? }
2、輪詢:nginx默認(rèn)就是輪詢其權(quán)重都默認(rèn)為1,服務(wù)器處理請(qǐng)求的順序:ABABABABAB....
upstream myweb {
server192.168.62.157:8080;
server192.168.62.158:8080;
?? }
3、加權(quán)輪詢:跟據(jù)配置的權(quán)重的大小而分發(fā)給不同服務(wù)器不同數(shù)量的請(qǐng)求。如果不設(shè)置,則默認(rèn)為1。下面服務(wù)器的請(qǐng)求順序?yàn)椋篈BBABBABBABBABB....
upstream myweb {
server192.168.62.157:8080weight=1;
server192.168.62.158:8080weight=2;
}
4、ip_hash:nginx會(huì)讓相同的客戶端ip請(qǐng)求相同的服務(wù)器。
upstream myweb {
server192.168.62.157:8080;
server192.168.62.158:8080;
? ?? ip_hash;
}
5、nginx負(fù)載均衡配置狀態(tài)參數(shù)
down,表示當(dāng)前的server暫時(shí)不參與負(fù)載均衡。
backup,預(yù)留的備份機(jī)器。當(dāng)其他所有的非backup機(jī)器出現(xiàn)故障或者忙的時(shí)候,才會(huì)請(qǐng)求backup機(jī)器,因此這臺(tái)機(jī)器的壓力最輕。
max_fails,允許請(qǐng)求失敗的次數(shù),默認(rèn)為1。當(dāng)超過最大次數(shù)時(shí),返回錯(cuò)誤。
fail_timeout,在經(jīng)歷了max_fails次失敗后,暫停服務(wù)的時(shí)間單位秒。max_fails可以和fail_timeout一起使用。
upstream myweb {
server192.168.62.157:8080weight=2max_fails=2fail_timeout=2;
server192.168.62.158:8080weight=1max_fails=2fail_timeout=1;
}
如果你像跟多更深入的了解 nginx 的負(fù)載均衡算法,nginx官方提供一些插件大家可以了解下。
4、nginx配置7層協(xié)議及4層協(xié)議方法(擴(kuò)展)
舉例講解下什么是7層協(xié)議,什么是4層協(xié)議。
(1)7層協(xié)議
OSI(Open System Interconnection)是一個(gè)開放性的通行系統(tǒng)互連參考模型,他是一個(gè)定義的非常好的協(xié)議規(guī)范,共包含七層協(xié)議。直接上圖,這樣更直觀些:

(2)4層協(xié)議
TCP/IP協(xié)議之所以說TCP/IP是一個(gè)協(xié)議族,是因?yàn)門CP/IP協(xié)議包括TCP、IP、UDP、ICMP、RIP、TELNETFTP、SMTP、ARP、TFTP等許多協(xié)議,這些協(xié)議一起稱為TCP/IP協(xié)議。
從協(xié)議分層模型方面來講,TCP/IP由四個(gè)層次組成:網(wǎng)絡(luò)接口層、網(wǎng)絡(luò)層、傳輸層、應(yīng)用層。

(3)協(xié)議配置
這里我們舉例,在nginx做負(fù)載均衡,負(fù)載多個(gè)服務(wù),部分服務(wù)是需要7層的,部分服務(wù)是需要4層的,也就是說7層和4層配置在同一個(gè)配置文件中。
準(zhǔn)備三臺(tái)機(jī)器:
代理服務(wù)IP:10.0.105.201 --配置本地host解析域名;
后端服務(wù)器IP:nginx-a :10.0.105.199/nginx-b:10.0.105.202(yum安裝)后端服務(wù)器將nginx服務(wù)啟動(dòng)
配置代理服務(wù)器的nginx配置文件
worker_processes4;
worker_rlimit_nofile102400;
events {
worker_connections1024;
}
?
http {
?? include ? ? ? 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? logs/access.log? main;
?
?? sendfile ? ? ?? on;
keepalive_timeout65;
?? gzip? on;
?
?? upstream testweb {
? ? ip_hash;
? ? server10.0.105.199:80weight=2max_fails=2fail_timeout=2s;
? ? server10.0.105.202:80weight=2max_fails=2fail_timeout=2s;
?? }
?? server {
listen80;
? ? ?? server_name? www.test.com;
? ? ?? charset utf-8;
#access_log? logs/host.access.log? main;
? ? ?? location / {
? ? proxy_pass http://testweb;
proxy_set_header Host$host:$server_port;
proxy_set_header X-Real-IP$remote_addr;
proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;
? ? ?? }
?
error_page500502503504/50x.html;
location=/50x.html {
? ? ? ? ?? root ? html;
? ? }
? ? }
?
?
? ? }
}
瀏覽器測(cè)試訪問:
10.0.105.202? 10.0.105.199服務(wù)器yum安裝的創(chuàng)建新的配置文件:
[root@nginx-server ~]# cd /etc/nginx/conf.d/
[root@nginx-server conf.d]# cp default.conf test.conf
[root@nginx-server conf.d]# cat test.conf
server {
listen80;
?? server_name? localhost;
?
?? location / {
? ? ? ? root ? /usr/share/nginx/html;
? ? ? ? index? index.html index.htm;
?? }
}
?
[root@nginx-server ~]# nginx -s reload
nginx在1.9.0的時(shí)候,增加了一個(gè) stream 模塊,用來實(shí)現(xiàn)四層協(xié)議(網(wǎng)絡(luò)層和傳輸層)的轉(zhuǎn)發(fā)、代理、負(fù)載均衡等。stream模塊的用法跟http的用法類似,允許我們配置一組TCP或者UDP等協(xié)議的監(jiān)聽,然后通過proxy_pass來轉(zhuǎn)發(fā)我們的請(qǐng)求,通過upstream添加多個(gè)后端服務(wù),實(shí)現(xiàn)負(fù)載均衡。
#4層tcp負(fù)載
stream {
? ? ? ? ? ? upstream myweb {
hash$remote_addrconsistent;
server172.17.14.2:8080;
server172.17.14.3:8080;
? ? ?? }
? ? ?? server {
listen80;
? ? ? ? ?? proxy_connect_timeout 10s;
? ? ? ? ?? proxy_timeout 30s;
? ? ? ? ?? proxy_pass myweb;
? ? ?? }
}
nginx 會(huì)話保持
nginx會(huì)話保持主要有以下幾種實(shí)現(xiàn)方式。
1、ip_hash
ip_hash使用源地址哈希算法,將同一客戶端的請(qǐng)求總是發(fā)往同一個(gè)后端服務(wù)器,除非該服務(wù)器不可用。
ip_hash語法:
upstream backend {
?? ip_hash;
?? server backend1.example.com;
?? server backend2.example.com;
?? server backend3.example.com down;
}
ip_hash簡單易用,但有如下問題:當(dāng)后端服務(wù)器宕機(jī)后,session會(huì)話丟失;同一客戶端會(huì)被轉(zhuǎn)發(fā)到同一個(gè)后端服務(wù)器,可能導(dǎo)致負(fù)載失衡;
2、sticky_cookie_insert
使用sticky_cookie_insert啟用會(huì)話親緣關(guān)系,這會(huì)導(dǎo)致來自同一客戶端的請(qǐng)求被傳遞到一組服務(wù)器的同一臺(tái)服務(wù)器。與ip_hash不同之處在于,它不是基于IP來判斷客戶端的,而是基于cookie來判斷。因此可以避免上述ip_hash中來自同一客戶端導(dǎo)致負(fù)載失衡的情況。(需要引入第三方模塊才能實(shí)現(xiàn))
sticky模塊
語法:
upstream backend {
?? server backend1.example.com;
?? server backend2.example.com;
?? sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;
}
?
server {
?? listen 80;
?? server_name 3evip.cn;
?? location / {
? ? ? ? proxy_pass http://backen;
?? }
}
說明:expires:設(shè)置瀏覽器中保持cookie的時(shí)間domain:定義cookie的域path:為cookie定義路徑
3.jvm_route
jvm_route的原理
一開始請(qǐng)求過來,沒有帶session信息,jvm_route就根據(jù)round robin的方法,發(fā)到一臺(tái)tomcat上面。
tomcat添加上session 信息,并返回給客戶。
用戶再此請(qǐng)求,jvm_route看到session中有后端服務(wù)器的名稱,它就把請(qǐng)求轉(zhuǎn)到對(duì)應(yīng)的服務(wù)器上。
nginx 實(shí)現(xiàn)動(dòng)靜分離
為了加快網(wǎng)站的解析速度,可以把動(dòng)態(tài)頁面和靜態(tài)頁面由不同的服務(wù)器來解析,加快解析速度。降低原來單個(gè)服務(wù)器的壓力。 在動(dòng)靜分離的tomcat的時(shí)候比較明顯,因?yàn)閠omcat解析靜態(tài)很慢,其實(shí)這些原理的話都很好理解,簡單來說,就是使用正則表達(dá)式匹配過濾,然后交個(gè)不同的服務(wù)器。
1、準(zhǔn)備環(huán)境
192.168.62.159 ? 代理服務(wù)器
192.168.62.157 ? 動(dòng)態(tài)資源
192.168.62.155 ? 靜態(tài)資源
準(zhǔn)備一個(gè)nginx代理 兩個(gè)http 分別處理動(dòng)態(tài)和靜態(tài)。
192.168.62.159 ? 代理服務(wù)器
?
1.配置nginx反向代理upstream;
[root@nginx-server conf.d]# cat upstream.conf
upstream static {
? ? ?? server 192.168.62.155:80 weight=1 max_fails=1 fail_timeout=60s;
? ? ?? }
upstream phpserver {
? ? ?? server 192.168.62.157:80 weight=1 max_fails=1 fail_timeout=60s;
? ? ?? }
? ? server {
? ? ?? listen ? ?? 80;
? ? ?? server_name ? ? localhost;
? ? ?? #動(dòng)態(tài)資源加載
? ? ?? location ~ \.(php|jsp)$ {
? ? ? ? ?? proxy_pass http://phpserver;
? ? ? ? ?? proxy_set_header Host $host:$server_port;
? ? ? ? ?? proxy_set_header X-Real-IP $remote_addr;
? ? ? ? ?? proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
? ? ? ? ? ? ?? }
? ? ?? #靜態(tài)資源加載
? ? ?? location ~ .*\.(html|gif|jpg|png|bmp|swf|css|js)$ {
? ? ? ? ?? proxy_pass http://static;
? ? ? ? ?? proxy_set_header Host $host:$server_port;
? ? ? ? ?? proxy_set_header X-Real-IP $remote_addr;
? ? ? ? ?? proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
? ? ? ? ? ? ?? }
? ? ?? }
?
192.168.62.155 ? 靜態(tài)資源
?
#靜態(tài)資源配置 ? 主配置文件-include /etc/nginx/conf.d/*.conf
# vim /etc/nginx/conf.d/static.conf
server {
listen80;
? ? ?? server_name ? ? localhost;
?
? ? ?? location ~ \.(html|jpg|png|js|css|gif|bmp|jpeg) {
? ? ?? root /home/www/nginx;
? ? ?? index index.html index.html;
? ? ?? }
}
?
[root@nginx-server2 nginx]# cat /home/www/nginx/index.html ?? //模擬靜態(tài)資源
hello155
192.168.62.157? 動(dòng)態(tài)資源
?
#動(dòng)態(tài)資源配置:
yum 安裝php7.1
[root@nginx-server ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
[root@nginx-server ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@nginx-server ~]# yum install php71w-xsl php71w php71w-ldap php71w-cli php71w-common php71w-devel php71w-gd php71w-pdo php71w-mysql php71w-mbstring php71w-bcmath php71w-mcrypt -y
[root@nginx-server ~]# yum install -y php71w-fpm
[root@nginx-server ~]# systemctl start php-fpm
[root@nginx-server ~]# systemctl enable php-fpm
編輯nginx的配置文件:
server {
listen80;
? ? ?? server_name ? ? localhost;
location ~ \.php$ {
root ? ? ? ? ? /home/nginx/html;#指定網(wǎng)站目錄
fastcgi_pass127.0.0.1:9000;#指定訪問地址
fastcgi_index? index.php;? ? ? #指定默認(rèn)文件
fastcgi_param? SCRIPT_FILENAME$document_root$fastcgi_script_name;#站點(diǎn)根目錄,取決于root配置項(xiàng)
include ? ? ?? fastcgi_params;#包含nginx常量定義
? ? ? ? }
}
[root@nginx-server1 html]# cat /home/nginx/html/index.php ? //模擬動(dòng)態(tài)資源
dongtai
當(dāng)訪問靜態(tài)頁面的時(shí)候location 匹配到 (html|jpg|png|js|css|gif|bmp|jpeg) 通過轉(zhuǎn)發(fā)到靜態(tài)服務(wù)器,靜態(tài)服務(wù)通過location的正則匹配來處理請(qǐng)求。
當(dāng)訪問動(dòng)態(tài)頁面時(shí)location匹配到 .\php 結(jié)尾的文件轉(zhuǎn)發(fā)到后端php服務(wù)處理請(qǐng)求。

