Nginx负载均衡
nginx不单可以作为强大的 web 服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、 ip 哈希、 URL 哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。
如果只有一台服务器时,这个服务器挂了,那么对于网站来说是个灾难.因此,这时候的负载均衡就会大显身手了,它会自动剔除挂掉的服务器.
安装Nginx
略
Nginx 负载均衡一些基础知识
nginx 的 upstream 目前支持 4 种方式的分配
- 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
- weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
- ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
- fair(第三方) 按后端服务器的响应时间来分配请求,响应时间短的优先分配。
- url_hash(第三方)
配置:
在http节点里添加
在需要使用负载的 Server节点下添加
1 upstream 每个设备的状态
2 down 表示单前 的server 暂时不参与负载
3 weight 默认为1. weight 越大,负载的权重就越大。
4 max_fails :允许请求失败的次数默认为 1.当超过最大次数时,返回 proxy_next_upstream 模块定义的错误
5 fail_timeoutmax_fails 次失败后,暂停的时间。
6 backup: 其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。
Nginx 还支持多组的负载均衡,可以配置多个 upstream 来服务于不同的 Server.
配置负载均衡比较简单,但是最关键的一个问题是怎么实现多台服务器之间 session 的共享
下面有几种方法(以下内容来源于网络,第四种方法没有实践.)
不使用 session,换作 cookie
能把 session改成 cookie,就能避开 session 的一些弊端,在从前看的一本 J2EE 的书上,也指明在集群系统中不能用 session,否则惹出祸端来就不好办。如果系统不复杂,就优先考虑能否将 session 去掉,改动起来非常麻烦的话,再用下面的办法。应用服务器自行实现共享
asp.net 可以用数据库或 memcached 来保存 session,从而在 asp.net 本身建立了一个session 集群,用这样的方式可以令 session 保证稳定,即使某个节点有故障,session也不会丢失,适用于较为严格但请求量不高的场合。但是它的效率是不会很高的,不适用于对效率 要求高的场合。
以上两个办法都跟 nginx 没什么关系,下面来说说用 nginx 该如何处理:
- ip_hash
nginx 中的 ip_hash 技术能够将某个 ip 的请求定向到同一台后端,这样一来这个 ip 下的某个客户端和某个后端就能建立起稳固的 session,ip_hash 是在 upstream配置中定义的12345upstream backend {server 127.0.0.18080 ;server 127.0.0.19090 ;ip_hash;}
ip_hash 是容易理解的,但是因为仅仅能用 ip 这个因子来分配后端,因此 ip_hash是有缺陷的,不能在一些情况下使用
nginx 不是最前端的服务器。ip_hash 要求 nginx 一定是最前端的服务器,否则 nginx 得不到正确 ip,就不能根据 ip 作 hash。譬如使用的是squid为最前端,那么 nginx 取 i p时只能得到 squid 的服务器 ip 地址,用这个地址来作分流是肯定错乱的。
nginx 的后端还有其它方式的负载均衡。假如 nginx 后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台 session应用服务器上。这么算起来,nginx 后端只能直接指向应用服务器,或者再搭一个 squid,然后指向应用服务器。最好的办法是用location 作一次分流,将需要 session 的部分请求通过 ip_hash 分流,剩下的走其它后端去。
- upstream_hash
为了解决 ip_hash 的一些问题,可以使用 upstream_hash 这个第三方模块,这个模块多数情况下是用作 url_hash 的,但是并不妨碍将它用来做 session 共享:
假如前端是 squid,他会将 ip 加入 x_forwarded_for 这个 http_header 里,用upstream_hash 可以用这个头做因子,将请求定向到指定的后端:
可见这篇文档:httpwww.sudone.comnginxnginx_url_hash.html
在文档中是使用 $request_uri 做因子,稍微改一下:
这样就改成了利用 x_forwarded_for 这个头作因子,在 nginx 新版本中可支持读取 cookie 值,所以也可以改成:
假如在php中配置的 session 为无 cookie方式,配合nginx自己的一个 userid_module 模块就可以用nginx自发一个 cookie,可参见 userid模块的英文文档:
httpwiki.nginx.orgNginxHttpUserIdModule
另可用姚伟斌编写的模块 upstream_jvm_route:httpcode.google.compnginx-upstream-jvm-route