Sticky工作原理
Sticky是nginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route
1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
Sticky的追加安装
nginx测试的版本:1.9.9,默认是不会安装Sticky模块的
1.进入https://www.nginx.com/resources/wiki/modules/index.html 下载相应stick的模块
2.重新编译nginx1.9.9,加入stick模块
进入nginx1.9.9的解压缩目录
./configure
–prefix=/usr/local/nginx
–with-http_stub_status_module
–with-http_ssl_module
–with-openssl=/usr/local/yuanyu/openssl-1.1.0g
–add-module=/usr/local/bigdata/nginx-goodies-nginx-sticky-module-ng-08a395c66e42
完全覆盖安装(注意,这是完全覆盖的,所以需要的模块全部加上)
make && make install
执行make && make install报错:src/core/ngx_sha1.h:19:17: fatal error: sha.h: No such file or directory
解决方法:yum --enablerepo=base --enablerepo=updates install openssl-devel
3.修改nginx配置文件,加上如下的红色配置
upstream leo_test{
sticky;
server 127.0.0.1:80;
}
4.进入nginx安装目录,检测语法是否正确
sbin/nginx -t
5.重启nginx
sbin/nginx -s reload
Sticky的配置
1.编辑配置文件nginx.conf
upstream wangpan.com {
sticky domain=sunruxue.cn;
server aly:18010;
server aly1:18020;
server aly2:18030;
}
注意:如果使用了Sticky模块,那么最好不要在server后面设置权重(weight),这样nginx不会根据浏览器cookie的route的值来转发到相应的后台服务器,即浏览器多次请求就会依据weight来变更route,会很错乱!如果请求正常,那么route将默认在浏览器关闭之前都不会改变,当然可以在sticky后面配置!
2.sticky的参数
语法:
sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h]
[hash=index|md5|sha1] [no_fallback] [secure] [httponly];
相关参数:
[name=route] 设置用来记录会话的cookie名称
[domain=.foo.bar] 设置cookie作用的域名
[path=/] 设置cookie作用的URL路径,默认根目录
[expires=1h] 设置cookie的生存期,默认不设置,浏览器关闭即失效,需要是大于1秒的值
[hash=index|md5|sha1] 设置cookie中服务器的标识是用明文还是使用md5值,默认使用md5
[no_fallback] 设置该项,当sticky的后端机器挂了以后,nginx返回502 (Bad Gateway or Proxy Error) ,而不转发到其他服务器,不建议设置
[secure] 设置启用安全的cookie,需要HTTPS支持
[httponly] 允许cookie不通过JS泄漏,没用过
3.其它的参数
语法:
session_sticky [cookie=name] [domain=your_domain] [path=your_path] [maxage=time] [mode=insert|rewrite|prefix] [option=indirect] [maxidle=time] [maxlife=time] [fallback=on|off] [hash=plain|md5]
参数说明:
1.mode设置cookie的模式:
insert: 在回复中本模块通过Set-Cookie头直接插入相应名称的cookie。
prefix: 不会生成新的cookie,但会在响应的cookie值前面加上特定的前缀,当浏览器带着这个有特定标识的cookie再次请求时,模块在传给后端服务前先删除加入的前缀,后端服务拿到的还是原来的cookie值,这些动作对后端透明。如:”Cookie: NAME=SRV~VALUE”。
rewrite: 使用服务端标识覆盖后端设置的用于session sticky的cookie。如果后端服务在响应头中没有设置该cookie,则认为该请求不需要进行session sticky,使用这种模式,后端服务可以控制哪些请求需要sesstion sticky,哪些请求不需要。
2.option设置用于session sticky的cookie的选项,可设置成indirect或direct。indirect不会将session sticky的cookie传送给后端服务,该cookie对后端应用完全透明。direct则与indirect相反。
3.maxidle设置session cookie的最长空闲的超时时间
4.maxlife设置session cookie的最长生存期
5.maxage是cookie的生存期。不设置时,浏览器或App关闭后就失效。下次启动时,又会随机分配后端服务器。所以如果希望该客户端的请求长期落在同一台后端服务器上,可以设置maxage。
6.hash不论是明文还是hash值,都有固定的数目。因为hash是server的标识,所以有多少个server,就有等同数量的hash值。
使用Sticky注意事项
1.同一客户端的请求,有可能落在不同的后端服务器上
如果客户端启动时同时发起多个请求。由于这些请求都没带cookie,所以服务器会随机选择后端服务器,返回不同的cookie。当这些请求中的最后一个请求返回时,客户端的cookie才会稳定下来,值以最后返回的cookie为准。
2.cookie不一定生效
由于cookie最初由服务器端下发,如果客户端禁用cookie,则cookie不会生效。
3.客户端可能不带cookie
Android客户端发送请求时,一般不会带上所有的cookie,需要明确指定哪些cookie会带上。如果希望用sticky做负载均衡,请对Android开发说加上cookie。
4.cookie名称不要和业务使用的cookie重名。Sticky默认的cookie名称是route,可以改成任何值。
5.客户端发的第一个请求是不带cookie的。服务器下发的cookie,在客户端下一次请求时才能生效。
6.Nginx sticky模块不能与ip_hash同时使用
相关资料
淘宝Tengine http://tengine.taobao.org/document_cn/http_upstream_session_sticky_cn.html