使用NGINX做负载均衡器时,常遇到如何将来自同一用户的访问始终定向到一台后端设备进行响应,一般nginx上面有下面办法来实现会话保持:
1、ip_hash nginx原生支持的基于IP地址来将不同的请求转发到同一台服务器进行响应,缺点就是如果前端用户都来自同一局域网,基于ip的负载方法会导致负载不均衡;
2、sticky 基于cookie来进行负载转发,保证将来自同一cookie的访问始终定向到同一服务器响应,缺点就是需要编译模块,而且,cookie需要浏览器支持。
Sticky是基于cookie的一种负载均衡解决方案,通过分发和识别cookie,使来自同一个客户端的请求落在同一台服务器上,默认cookie标识名为route :
1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
sticky模块下载,1.1以后这个项目已经从谷歌code搬家到https://bitbucket.org,bitbucket上提供了zip、bz2、gz格式的包 ,官网下载:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/downloads/?tab=tags
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c: In function ‘ngx_http_sticky_misc_md5’:
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:152: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function)
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:152: error: (Each undeclared identifier is reported only once
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:152: error: for each function it appears in.)
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:152: warning: unused variable ‘hash’
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c: In function ‘ngx_http_sticky_misc_hmac_md5’:
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:189: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function)
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:190: error: ‘MD5_CBLOCK’ undeclared (first use in this function)
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:190: warning: unused variable ‘k’
/opt/nginx_install/package/openresty-1.15.8.3/../nginx-goodies-nginx-sticky-module-ng-1.2.6/ngx_http_sticky_misc.c:189: warning: unused variable ‘hash’
进入sticky模块的目录编辑ngx_http_sticky_misc.c ,新增以下两行
#include <openssl/sha.h>
#include <openssl/md5.h>
保存退出,重新编译
#include <nginx.h>
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_md5.h>
#include <ngx_sha1.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
编译安装nginx以后,在nginx.conf 的upstream中使用sticky 引入即可。
upstream app {
sticky expires=1h domain=xxx.xxx.com ;
server 172.18.8.205:8080;
server 172.18.8.206:8080;
}
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的生存期,默认不设置,浏览器关闭即失效
[hash=index|md5|sha1] 设置cookie中服务器的标识是用明文还是使用md5值,默认使用md5
[no_fallback] 设置该项,当sticky的后端机器挂了以后,nginx返回502 (Bad Gateway or Proxy Error) ,而不转发到其他服务器,不建议设置
[secure] 设置启用安全的cookie,需要HTTPS支持
[httponly] 允许cookie不通过JS泄漏,没用过
1.同一客户端,如果启动时同时发起多个请求,有可能落在不同的后端服务器上
2.由于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同时使用
https://blog.csdn.net/zhuyu19911016520/article/details/91351773
https://blog.csdn.net/woshiji594167/article/details/85338045