🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 12. 作为负载均衡器 #### 1. 介绍 众所周知,nginx是以高并发和内存占用少出名,它是一个http服务器,也是反向代理服务器,它更是负载均衡器。作为负载均衡器,在版本1.9之前,它只能作为http的负载均衡,也就是在网络模型的第七层发挥作用,1.9之后,它可以对tcp进行负载均衡,比如redis,mysql等。 nginx的负载均衡是出了名的简单,它跟反向代理的功能是紧密结合在一起的。比如下面是我网站上的一段配置: ``` 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; } } ``` 我在服务器上部署的是ruby on rails项目,用unicorn来跑ruby的代码,它是监听在一个unix socket上的,也就是`unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock`这个文件,`proxy_pass http://rails365;`是反向代理到上游服务器,也就是unicorn的部分,`upstream`这里指的就是上游服务器的部分。 #### 2. 使用 要实现负载均衡很简单,我在部署多一个unicorn进程,监听在另外的unix socket上,就等于多了一台服务器,只需这样做: ``` 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`指令添加多一行服务器就可以了。 现在有两个上游服务器了,以前是一个,那么是如何以什么样的方式访问这两个上游服务器的呢。 默认情况下,如果不指定方式,就是随机轮循(round-robin)。两个socket被不能地随机访问,这点可以通过监控日志看到的。 #### 3. 参数讲解 接下来,我们来讲一下nginx负载均衡在使用和配置上的一些参数。 上面有说过一个参数叫`round-robin`的,除了它之外,还有其他的几个。 ##### 3.1 least\_conn 它是优先发送给那些接受请求少的,目的是为了让请求分发得更平衡些。 ``` 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,如果是同一个ip,下次访问的时候还是会到相同的主机,这个可以略微解决那种带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参数所设置的是根据相同的ip访问相同的主机,这种是根据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 假如有一台主机是出了故障,或者下线了,要暂时移出,那可以把它标为down,表示请求是会略过这台主机的。 ``` 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`是指备份的机器,相对于备份的机器来说,其他的机器就相当于主要服务器,只要当主要服务器不可用的时候,才会用到备用服务器。 ``` 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`指的是权重,默认情况下,每台主机的权重都是1,也就是说,接收请求的次数的比例是一样的。但我们可以根据主机的配置或其他情况自行调节,比如,对于配置高的主机,可以把`weight`值调大。 ``` upstream myapp1 { server srv1.example.com weight=3; server srv2.example.com; server srv3.example.com; } ``` 假如有五个请求,srv1可能会得到三个,其他的两台服务器,可能分别得到1个。 ##### 3.7 max\_fails和fail\_timeout 默认情况下,max\_fails的值为1,表示的是请求失败的次数,请求1次失败就换到下台主机。 另外还有一个参数是fail\_timeout,表示的是请求失败的超时时间,在设定的时间内没有成功,那作为失败处理。 ``` 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; } ``` 那什么情况才叫请求失败呢?有可能是服务器内部错误,超时,无效的头部,或返回500以上的状态码的时候。 完结。