# 12. 作為負(fù)載均衡器
#### 1. 介紹
眾所周知,nginx是以高并發(fā)和內(nèi)存占用少出名,它是一個(gè)http服務(wù)器,也是反向代理服務(wù)器,它更是負(fù)載均衡器。作為負(fù)載均衡器,在版本1.9之前,它只能作為http的負(fù)載均衡,也就是在網(wǎng)絡(luò)模型的第七層發(fā)揮作用,1.9之后,它可以對tcp進(jìn)行負(fù)載均衡,比如redis,mysql等。
nginx的負(fù)載均衡是出了名的簡單,它跟反向代理的功能是緊密結(jié)合在一起的。比如下面是我網(wǎng)站上的一段配置:
```
upstream rails365 {
# Path to Unicorn SOCK file, as defined previously
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80 default_server;
# listen [::]:80 default_server ipv6only=on;
server_name www.rails365.net;
root /home/yinsigan/rails365/current/public;
keepalive_timeout 70;
location ~ ^/assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
# add_header ETag "";
# break;
}
try_files $uri/index.html $uri @rails365;
location @rails365 {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://rails365;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
```
我在服務(wù)器上部署的是ruby on rails項(xiàng)目,用unicorn來跑ruby的代碼,它是監(jiān)聽在一個(gè)unix socket上的,也就是`unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock`這個(gè)文件,`proxy_pass http://rails365;`是反向代理到上游服務(wù)器,也就是unicorn的部分,`upstream`這里指的就是上游服務(wù)器的部分。
#### 2. 使用
要實(shí)現(xiàn)負(fù)載均衡很簡單,我在部署多一個(gè)unicorn進(jìn)程,監(jiān)聽在另外的unix socket上,就等于多了一臺服務(wù)器,只需這樣做:
```
upstream rails365 {
# Path to Unicorn SOCK file, as defined previously
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock;
}
```
很簡單,只要用`server`指令添加多一行服務(wù)器就可以了。
現(xiàn)在有兩個(gè)上游服務(wù)器了,以前是一個(gè),那么是如何以什么樣的方式訪問這兩個(gè)上游服務(wù)器的呢。
默認(rèn)情況下,如果不指定方式,就是隨機(jī)輪循(round-robin)。兩個(gè)socket被不能地隨機(jī)訪問,這點(diǎn)可以通過監(jiān)控日志看到的。
#### 3. 參數(shù)講解
接下來,我們來講一下nginx負(fù)載均衡在使用和配置上的一些參數(shù)。
上面有說過一個(gè)參數(shù)叫`round-robin`的,除了它之外,還有其他的幾個(gè)。
##### 3.1 least\_conn
它是優(yōu)先發(fā)送給那些接受請求少的,目的是為了讓請求分發(fā)得更平衡些。
```
upstream rails365 {
least_conn;
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock;
}
```
##### 3.2 ip\_hash
`ip_hash`可以記錄請求來源的ip,如果是同一個(gè)ip,下次訪問的時(shí)候還是會到相同的主機(jī),這個(gè)可以略微解決那種帶cookie,session的請求的一致性問題。
```
upstream rails365 {
ip_hash;
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock;
}
```
##### 3.3 hash
上面ip\_hash參數(shù)所設(shè)置的是根據(jù)相同的ip訪問相同的主機(jī),這種是根據(jù)ip地址,還有一種粒度更小的控制,可以通過任何變量來控制。
比如下面的例子就是通過請求地址($request\_uri)來控制。
```
upstream backend {
hash $request_uri consistent;
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock;
}
```
##### 3.4 down
假如有一臺主機(jī)是出了故障,或者下線了,要暫時(shí)移出,那可以把它標(biāo)為down,表示請求是會略過這臺主機(jī)的。
```
upstream rails365 {
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock down;
}
```
##### 3.5 backup
`backup`是指備份的機(jī)器,相對于備份的機(jī)器來說,其他的機(jī)器就相當(dāng)于主要服務(wù)器,只要當(dāng)主要服務(wù)器不可用的時(shí)候,才會用到備用服務(wù)器。
```
upstream rails365 {
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock backup;
}
```
##### 3.6 weight
`weight`指的是權(quán)重,默認(rèn)情況下,每臺主機(jī)的權(quán)重都是1,也就是說,接收請求的次數(shù)的比例是一樣的。但我們可以根據(jù)主機(jī)的配置或其他情況自行調(diào)節(jié),比如,對于配置高的主機(jī),可以把`weight`值調(diào)大。
```
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}
```
假如有五個(gè)請求,srv1可能會得到三個(gè),其他的兩臺服務(wù)器,可能分別得到1個(gè)。
##### 3.7 max\_fails和fail\_timeout
默認(rèn)情況下,max\_fails的值為1,表示的是請求失敗的次數(shù),請求1次失敗就換到下臺主機(jī)。
另外還有一個(gè)參數(shù)是fail\_timeout,表示的是請求失敗的超時(shí)時(shí)間,在設(shè)定的時(shí)間內(nèi)沒有成功,那作為失敗處理。
```
upstream rails365 {
server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock max_fails=2;
server unix:///home/yinsigan/rails365_cap/shared/tmp/sockets/unicorn.sock backup;
}
```
那什么情況才叫請求失敗呢?有可能是服務(wù)器內(nèi)部錯(cuò)誤,超時(shí),無效的頭部,或返回500以上的狀態(tài)碼的時(shí)候。
完結(jié)。
- 介紹
- 安裝
- 1. 基本介紹和配置文件語法
- 2. 反向代理
- 3. gzip 壓縮提升網(wǎng)站性能
- 4. 在線升級
- 5. 監(jiān)控工具 ngxtop
- 6. 編譯第三方模塊
- 7. auth_basic 模塊使用
- 8. 日志分析工具
- 9. 用 nginx 搭建谷歌鏡像網(wǎng)站
- 10. 自制啟動腳本
- 11. 日志切割
- 12. 作為負(fù)載均衡器
- 13. 開啟 debug 模式
- 14. gzip static 模塊探索
- 15. 安裝最新 nginx 的另類方法
- 16. 使用 acme.sh 安裝 Let’ s Encrypt 提供的免費(fèi) SSL 證書
- 17. 給 GitLab 應(yīng)用加上 https
