1. nginx-sticky-module
这个模块的作用是通过cookie的方式将来自同一个客户端(浏览器)的请求发送到同一个后端服务器上处理,这样一定程度上可以解决多个backend servers的session同步的问题 —— 因为不再需要同步,而RR轮询模式必须要运维人员自己考虑session同步的实现。
另外内置的 ip_hash 也可以实现根据客户端IP来分发请求,但它很容易造成负载不均衡的情况,而如果nginx前面有CDN网络或者来自同一局域网的访问,它接收的客户端IP是一样的,容易造成负载不均衡现象。淘宝Tengine的 ngx_http_upstream_session_sticky_module 也是类似的功能。nginx-sticky-module的cookie过期时间,默认浏览器关闭就过期,也就是会话方式。
这个模块并不合适不支持 Cookie 或手动禁用了cookie的浏览器,此时默认sticky就会切换成RR。它不能与ip_hash同时使用。
原理其实很简单,当一个客户端请求过来时,会 set-cookie 一个 cookie 来标注本次请求的服务器(第一次是随机).然后下次请求都会包含这个 cookie .然后就能很好的区分原本请求的服务器了.我测试过,当默认请求的后端服务器死掉后,会还是会自动切换的.另外,这个模块并不合适对不支持 Cookie 的浏览器
Sticky module is based on a "best effort" algorithm. Its aim is not to handle security somehow. It's been made to ensure that normal users are always redirected to the same backend server: that's all!
sticky安装
./configure ... --add-module=/absolute/path/to/nginx-sticky-module-ng make make install
sticky配置
upstream { sticky; server 127.0.0.1:9000; server 127.0.0.1:9001; server 127.0.0.1:9002; } sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h] [hash=index|md5|sha1] [no_fallback] [secure] [httponly];
- name: the name of the cookies used to track the persistant upstream srv; default: route
- domain: the domain in which the cookie will be valid default: nothing. Let the browser handle this.
- path: the path in which the cookie will be valid default: /
- expires: the validity duration of the cookie default: nothing. It's a session cookie. restriction: must be a duration greater than one second
- hash: the hash mechanism to encode upstream server. It cant' be used with hmac. default: md5hmac: the HMAC hash mechanism to encode upstream server It's like the hash mechanism but it uses hmac_key to secure the hashing. It can't be used with hash. md5|sha1: well known hash default: none. see hash.
- md5|sha1: well known hash
- index: it's not hashed, an in-memory index is used instead, it's quicker and the overhead is shorter Warning: the matching against upstream servers list is inconsistent. So, at reload, if upstreams servers has changed, index values are not guaranted to correspond to the same server as before! USE IT WITH CAUTION and only if you need to!
- hmac_key: the key to use with hmac. It's mandatory when hmac is set default: nothing.
- no_fallback: when this flag is set, nginx will return a 502 (Bad Gateway or Proxy Error) if a request comes with a cookie and the corresponding backend is unavailable.
- secure enable secure cookies; transferred only via https
- httponly enable cookies not to be leaked via js
官方文档也有个 sticky 指令,作用几乎是一样的,但这是nginx商业版本里才有的特性。包括后面的check
指令,在nginx的商业版本里也有对应的health_check
(配在 location )实现几乎一样的监控检查功能。
2、nginx负载均衡
- 轮询(默认) : 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
- ip_hash : 每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。当然如果这个节点不可用了,会发到下个节点,而此时没有session同步的话就注销掉了。
- least_conn : 请求被发送到当前活跃连接最少的realserver上。会考虑weight的值。
- url_hash : 此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装nginx 的hash软件包 nginx_upstream_hash 。
- fair : 这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair 模块。
ip_hash的配置
upstream backend { ip_hash; server 192.168.1.225:8080 weight 2; server 192.168.1.226:8080 weight=1 max_fails=2 fail_timeout=30s ; server 192.168.1.227:8080 backup; } server { location / { proxy_pass http://backend; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; } }
- weight:轮询权值也是可以用在ip_hash的,默认值为1
- max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
- fail_timeout:有两层含义,一是在 30s 时间内最多容许 2 次失败;二是在经历了 2 次失败以后,30s时间内不分配请求到这台服务器。
- backup:备份机器。当其他所有的非backup机器出现故障的时候,才会请求backup机器
- max_conns: 限制同时连接到某台后端服务器的连接数,默认为0即无限制。因为queue指令是commercial,所以还是保持默认吧。
- proxy_next_upstream:这个指令属于 http_proxy 模块的,指定后端返回什么样的异常响应时,使用另一个realserver
项目地址:
https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng
https://code.google.com/p/nginx-sticky-module/
3、 upstream_check
nginx自带是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的 ngx_http_proxy_module 模块和 ngx_http_upstream_module 模块中的相关指令来完成当后端节点出现故障时,自动切换到下一个节点来提供访问。
nginx_upstream_check_module 是专门提供负载均衡器内节点的健康检查的外部模块,由淘宝工程师开发,通过它可以用来检测后端 realserver 的健康状态。如果后端 realserver 不可用,则后面的请求就不会转发到该节点上,并持续检查几点的状态。在淘宝自己的 tengine 上是自带了该模块。
upstream backend { sticky; server 192.168.1.225:8080 weight=2; server 192.168.1.226:8081 weight=1 max_fails=2 fail_timeout=30s ; server 192.168.1.227:8080 weight=1 max_fails=2 fail_timeout=30s ; server 192.168.1.227:8081; check interval=5000 rise=2 fall=3 timeout=1000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; } server { location / { proxy_pass http://backend; } location /status { check_status; access_log off; allow 192.168.1.0/24; deny all; } }