在我们做Nginx负载均衡的时候经常会遇到会话保持的问题,为了保证同一用户session会被分配到同一台服务器上,这时就需要会话保持,我们常用的方法有基于ip_hash的会话保持、基于cookie的会话保持。
1、基于ip_hash的会话保持
IP哈希(IP Hash)负载均衡策略根据客户端IP计算出哈希值,然后把请求分配给该数值对应的被代理服务器。在哈希值不变且被代理服务器可用的前提下,同一客户端的请求始终会被分配到同一台被代理服务器上。IP哈希负载均衡策略常被应用在会话(Session)保持的场景。
HTTP客户端在与服务端交互时,因为HTTP协议是无状态的,所以任何需要上下文逻辑的情景都必须使用会话保持机制,会话保持机制是通过客户端存储由唯一的Session ID进行标识的会话信息,每次与服务器交互时都会将会话信息提交给服务端,服务端依照会话信息实现客户端请求上下文的逻辑关联。会话信息通常存储在被代理服务器的内存中,如果负载均衡将客户端的会话请求分配给其他被代理服务器,则该会话逻辑将因为会话信息失效而中断。所以为确保会话不中断,需要负载均衡将同一客户端的会话请求始终都发送到同一台被代理服务器,通过会话保持实现会话信息的有效传递。
http {
upstream backend {
ip_hash; # 启用IP哈希负载均衡策略
server a weight=5;
server b weight=1;
server c weight=1;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
通过url 的维持会话保持
http {
upstream backend {
hash $cookie_jsessionid; # 基于cookie中的jessionid这个key进行hash调度,实现会话绑定
hash $request_uri; # 基于用户请求的uri做简单hash
server a weight=5;
server b weight=1;
server c weight=1;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
::: warning
注意:使用$cookie_jsessionid时要查看cookie中是否有jsessionid及value
:::
2、基于cookie的会话保持
目前只有商业版Nginx Plus支持基于cookie的会话保持,对于开源版本可以通过第三方模块nginx-sticky-module-ng实现。启用基于cookie的会话保持功能时,可以使同一客户端的请求始终转发给同一后端服务器。
sticky,根据服务器给客户端的cookie,客户端再次请求时会带上此cookie,nginx会把有此cookie的请求转发到颁发cookie的服务器上
1、sticky原理
Sticky是基于cookie的一种负载均衡解决方案,通过分发和识别cookie,使来自同一个客户端的请求落在同一台服务器上,默认cookie标识名为route :
- 客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
- 后端服务器处理完请求,将响应数据返回给nginx。
- 此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值。
- 客户端接收请求,并保存带route的cookie。
- 当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
2、安装Sticky模块
wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
tar xf master.tar.gz
#把此模块放进nginx/module目录下,名称太长,重命名一下
mkdir /usr/local/nginx/module
mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 /usr/local/nginx/module/nginx-sticky-module
./configure --add-module=/usr/local/nginx/module/nginx-sticky-module #在此载入sticky模块
3、修改NGINX配置文件
mkdir /usr/local/nginx/ngx_cookie
upstream backend {
sticky name=ngx_cookie expires=6h;
server 192.168.31.240:8080 weight=3 max_fails=3 fail_timeout=10s;
server 192.168.31.241:8080 weight=3 max_fails=3 fail_timeout=10s;
server 192.168.31.242:8080 weight=6 max_fails=3 fail_timeout=10s;
server 192.168.31.243:8080;
server 192.168.31.244:8080 down;
}
评论区