本次实验是在Nginx架构——nginx+tomcat搭建nginx反向代理实现tomcat负载均衡基础上进行的,已经搭建了lnmp+memcache+openresty+tomcat+jsp并且配置了tomcat负载均衡,可参考上一篇搭建出相同环境。存在的问题是会发生数据丢失。
接下来我将配置sticky粘制模块实现tomcat负载均衡中的会话保持。
文章目录
- 一、nginx会话保持之nginx-sticky-module模块
- 1、为什么要会话保持
- 2、Nginx反向代理实现会话(session)保持的两种方式
- (1)ip_hash
- (2)sticky_cookie_insert
- 2、Sticky工作原理
- 3、区别会话和连接
- 二、配置sticky粘制模块实现tomcat负载均衡中的会话保持
- 实验环境
- 实验
- 总结
一、nginx会话保持之nginx-sticky-module模块
1、为什么要会话保持
常见的异常场景包括:
- 客户端输入了正确的用户名和密码,但却反复跳到登录页面;
- 客户端放入购物篮的物品丢失;
- 用户输入了正确的验证码,但是总提示验证码错误
因此,会话保持机制的意义就在于,确保将来自相同客户端的请求,转发至后端相同的服务器进行处理。如果在客户端和服务器之间部署了负载均衡设备,很有可能,这多个连接会被转发至不同的服务器进行处理。如果服务器之间没有会话信息的同步机制,会导致其他服务器无法识别用户身份,造成用户在和应用系统发生交互时出现异常。
2、Nginx反向代理实现会话(session)保持的两种方式
(1)ip_hash
ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用。
ip_hash语法:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
标记为“down”,当原来为4台后端服务时,摘除backend3.example后,Nginx仍然会按4台服务器进行哈希。如果直接注释掉“server backend3.example.com”这行,Nginx就会按照3台服务器进行重新
ip_hash简单易用,但有如下问题:
- 当后端服务器宕机后,session会丢失;
- 来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;
- 不适用于CDN网络,不适用于代理的情况。
(2)sticky_cookie_insert
使 用sticky_cookie_insert启用会话亲缘关系,这会导致来自同一客户端的请求被传递到一组服务器在同一台服务器。与ip_hash不同之 处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。因此可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的 情况。
语法:
upstream backend {
server backend1.example.com;
server backend2.example.com; sticky_cookie_insert srv_id expires=1h domain=xxxx.com path=/;}
说明:
expires:设置浏览器中保持cookie的时间
domain:定义cookie的域
path:为cookie定义路径
2、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值,转发给对应的后端服务器。
打个比方,我们去银行办理储蓄业务,第一次给你办了张银行卡,里面存放了身份证、密码、手机等个人信息。当你下次再来这个银行时,银行机器能识别你的卡,从而能够直接办理业务。
3、区别会话和连接
连接: 我们都知道TCP/IP协议中经常提到的:”三次握手,四次挥手“的问题。自然也知道客户端和服务器端是经过三次握手以后,建立了连接(connection)。当它们建立了连接以后,那么客户端就可以向服务端发送多次的请求。如果客户端和服务器端需要断开连接,那么就需要经过四次的挥手过程才能够断开连接。
会话: 如果用户需要登录,那么可以理解为经过三次握手以后,客户端与服务器端建立的就是会话(session)。如果用户不需要登录,那么可以理解为经过三次握手以后,客户端与服务器端建立的就是连接(connection).
从简单的角度来看,如果用户需要登录,那么就可以简单的理解为会话;如果不需要登录,那么就是连接
。
二、配置sticky粘制模块实现tomcat负载均衡中的会话保持
实验环境
主机名 | ip | 服务 | 版本 |
server1 | 172.25.1.101 | lnmp+memcache+openresty+tomcat+jsp+sticky | rhel6.5 |
server2 | 172.25.1.102 | tomcat+jsp | rhel6.5 |
真机 | 172.25.1.250 | 客户端 | rhel7.3 |
实验
您如果未配置openresty,我在下面的操作中,涉及/usr/local/openresty目录内的操作,您均在/usr/local/nginx目录中操作即可。
在server1上:
步骤一:在网上下载nginx-sticky-module安装包,解压到指定目录
tar zxf nginx-sticky-module-ng.tar.gz -C /usr/local/
步骤二:关闭openresty的nginx
/usr/local/openresty/nginx/sbin/nginx -s stop
步骤三:重新编译,添加nginx-sticky-module模块
cd nginx-1.17.8
./configure --prefix=/usr/local/lnmp/nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-threads --with-file-aio \
--user=nginx --group=nginx \
--add-module=/usr/local/nginx-sticky-module-ng
make
步骤四:替换二进制文件
新版本通过编译之后,源码包里的objs目录里便有了新的nginx文件,替换原来的nginx二进制文件
cd nginx-1.17.8
cd objs/
cp -f nginx /usr/local/openresty/nginx/sbin/nginx
##-f 强制,
步骤五:编辑nginx配置文件,我直接复制之前的openresty下的nginx配置文件,修改即可
vim /usr/local/openresty/nginx/conf/nginx.conf
17 http {
18 upstream tomcat{
19 sticky;
20 server 172.25.2.1:8080;
21 server 172.25.2.2:8080;
22 }
步骤六:并启动nginx,查看端口
/usr/local/openresty/nginx/sbin/nginx
netstat -antuple
步骤七:访问测试页http://172.25.1.101/test.jsp
在server2上:
关闭tomcat
cd /usr/local/tomcat/bin
./shutdown.sh
在真机上:
刷新浏览器:
总结
可以看出客户连接到tomcat后会一直与同一台tomcat服务器保持会话,即使次tomcat服务器宕机,切换到另外一台tomcat服务器上面依然可以实现会话保持。但是此时在第一个tomcat主机上面的数据会丢失。用一个简单的例子来说:用户登陆到淘宝页面后,可以无限次查询,保持会话。但是保存此客户信息的服务器突然宕机,所有客户信息丢失。具体解决方法见下一篇。