Nginx的Upstream

作者 Gavin 日期 2016-01-25
Nginx的Upstream

之前对于Nginx的upstream理解的有点肤浅,只是把它作为简单的反向代理和负载均衡用,最近在实际项目中发现upstream在用来做负载均衡的时候可以解决单点问题。

简单说,假设现在有两台Server:ServerA和ServerB,默认都是使用80端口,当ServerA不可用或者ServerA的80端口不可用时,会暂时从负载均衡Server“队列”中被“摘除掉”,在不可用期间Nginx不会把请求发送到ServerA,直到ServerA的80端口可用为止。

看下官方Doc:

If an error occurs during communication with a server, the request will be passed to the next server, and so on until all of the functioning servers will be tried. If a successful response could not be obtained from any of the servers, the client will receive the result of the communication with the last server.

当一台Server不可用时,Nginx会把请求发送到下一台Server上,直到所有的Server被重试完…

这其实在实际的生产项目中是很有用的,如果我们后台的服务是N台Server,当其中最多N-1台Server Down掉时,是不影响我们的访问的(按概率事件算,所有Server同时Down掉的几率可以算作0%),或者说我们可以随意停掉、重启某台或者某几台Server。

实例为证:

Nginx配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
http {
upstream up_test
{
server guojianxiang.com:83 weight=5 max_fails=2 fail_timeout=3s;
server guojianxiang.com:84 weight=5 max_fails=2 fail_timeout=3s;
}
}
server {
server_name guojianxiang.com;
listen 85;
location / {
proxy_pass http://up_test/;
}
}
server {
server_name guojianxiang.com;
listen 83;
access_log logs/guojianxiang-83.log;
root /xxx/index1;
location / {
index index.html index.php index.htm;
}
}
server {
server_name guojianxiang.com;
listen 84;
access_log logs/guojianxiang-84.log;
root /xxx/index2;
location / {
index index.html index.php index.htm;
}
}

/xxx/index1/index.html

1
This is 1

/xxx/index2/index.html

1
This is 2

当访问 http://guojianxiang.com:85/ 时,由于我设的weight是一样的,我们会看到index1和index2是交叉出现的,当我把83端口关掉后或者我们修改下 upstream 使用一个不可用的端口,是丝毫不影响正常访问。

我们也可以利用upstream做反向代理。例如我的 robot ,我用upstream做了反向代理,当websocket请求过来后就由nginx代理到我本地的一个端口,由一个监听该端口的服务去处理请求并返回Response。

在分布式的系统中,这种避免单点问题的方式也还可以使用zookeeper来解决,后面有时间再整理下zk在分布式中的应用实例 ~