我们都知道Nginx具有负载均衡的功能,纯 ip_hash 像局域网内的访问ip访问会导致ip倾斜 ,cookie_hash服务器给客户端下发一个cookie,具有特定cookie的请求会分配给它的发布者,cookie需要浏览器支持。
基本介绍
Sticky就是基于cookie的一种负载均衡解决方案,它是通过基于cookie实现客户端与后端服务器的会话保持, 在一定条件下可以保证同一个客户端访问的都是同一个后端服务器。请求来了,服务器发个cookie,并说:下次来带上,直接来找我。
Sticky是nginx的一个模块,它是基于cooki e的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route
- 1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
- 2.后端服务器处理完请求,将响应数据返回给nginx。
- 3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值
- 4.客户端接收请求,并保存带route的cookie。
- 5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
如果浏览器不支持cookie,那么sticky不生效,整个模块是给予cookie实现的。
Sticky的安装
下载地址
nginx-goodies / nginx-sticky-module-ng / Downloads — Bitbucket
https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/downloads/
- 1)下载完成,放入服务器解压,记住解压的位置
- 2)进入到nginx的安装文件
- 3)配置nginx
./configure \ --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --add-module=/tmp/sticky-module/nginx-goodies-nginx-sticky-module-ng
- 红色部分修改为你解压后的路径
- 最后重新启动Nginx即可
make 编译的时候有可能会报错 修改:找到sticky刚刚的解压目录,进入修改文件 vim ngx_http_sticky_misc.h ,加入下面的头文件 #include <openssl/sha.h> #include <openssl/md5.h>
nginx 启动 停止 重启命令
/usr/local/nginx-1.9.9/sbin/nginx -s start
/usr/local/nginx1.9.9/sbin/nginx -s stop
/usr/local/nginx1.9.9/sbin/nginx -s reload
配置使用sticky
upstream iphashserver {
sticky; server www.test.com:8001; server www.test.com:8002; }</code></pre></div></div><p>具体可以附加参数如下: </p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h] [hash=index|md5|sha1] [no_fallback] [secure] [httponly];</code></pre></div></div><p>参数信息说明:</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">[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泄漏,没用过
注意点说明
- .同一客户端的请求,有可能落在不同的后端服务器上如果客户端启动时同时发起多个请求。由于这些请求都没带cookie,所以服务器会随机选择后端服务器,返回不同的cookie。当这些请求中的最后一个请求返回时,客户端的cookie才会稳定下来,值以最后返回的cookie为准。
- cookie不一定生效由于cookie最初由服务器端下发,如果客户端禁用cookie,则cookie不会生效。
- 客户端可能不带cookie,Android客户端发送请求时,一般不会带上所有的cookie,需要明确指定哪些cookie会带上。如果希望用sticky做负载均衡,请对Android开发说加上cookie。
- cookie名称不要和业务使用的cookie重名。Sticky默认的cookie名称是route,可以改成任何值。
- 客户端发的第一个请求是不带cookie的。服务器下发的cookie,在客户端下一次请求时才能生效。
- Nginx sticky模块不能与ip_hash同时使用