Session共享的解决方案

Tomcat下集群Session共享的4个方案

问题引入

在这个分布式结构下,如果不用共享session的话,就会出现问题。当一个客户端发送一个请求(无session),通过nginx将第一次请求分发给服务器1,服务器判断无session,就让那个客户进行登录操作,并得到响应,此时客户端会存储一个来自服务器1响应的session,并存储在客户端。

当客户端发送第二次请求的时候,此时本次请求已经携带了session(跳过登录),nginx却将请求分发给服务器2,因为服务器2中没有session,所以无法与客户端session进行对应。所以程序会出现异常或是报错,无法正常响应。

Session共享的解决方案_第1张图片

1.Tomcat内置的Session复制方案

通过修改Tomcat相关的配置文件里面的配置,从而实现Tomcat集群中每个Tomcat都会储存其他Tomcat里面的Session,从而实现Tomcat集群中每台Tomcat的Session共享

优点:

  • Java代码上不需要做任何修改

缺点:

  • 依赖应用服务器容器,这里是Tomcat,其他的容器是使用不了的;

  • 适合小集群,不适合大集群,因为Session的复制是 all to all的,每个Tomcat都会存储其他的Session,会造成很大的资源浪费

在高并发的情况下延迟较为严重且占用网络资源。

2.使用Session粘滞方案

可以通过某种形式,将用户的每次请求都固定到某一台机器上。例如通过Nginx的ip_hash策略进行负载均衡,只要用户的IP固定不变,总能访问到同一台服务器上。举例如下:

upstream backend{
	
    ip_hash;
    server 192.168.128.1:8080 ;
    server 192.168.128.2:8080 ;
}
server {
    listen 8081;
    server_name test.csdn.net;
    root /home/system/test.csdn.net/test;
    location ^~ /Upload/upload {
    	proxy_pass http://backend;
    }
}

优点:

  • 不需要修改项目代码,没有额外开销

缺点:

  • 如果某台服务器挂掉了,Session丢失,所有被分发到这台服务器的请求都会发生故障,然后转向其他服务器,从而重新登录进行操作;

  • 如果是某一个局域网大量用户同时登录,这样负载均衡就没什么作用了。

3.基于Session持久化方案

将Session存储到Mysql数据库中(一般很少用这种方案)

优点:

  • 可以从数据中查询Session中存储的相关数据

缺点:

  • 要是海量请求同时发送,请求数据库,容易造成数据库的压力过大从而崩溃

4.使用Redis解决(我们的方案)

使用Redis解决是基于token实现的,没发起一次请求都会携带token。而如果用户要是存在的话,用户信息就会存储到Redis中。每次发送请求的时候,都会携带token,而后台获取token从而查询Redis中是否存在相关用户的相关信息,这样不管是任何一台服务器,都会从Redis中查询相关信息。这样就解决了Tomcat集群下Session无法共享的问题,而Redis也可以对相关信息进行脱敏处理,一定程度上保证了安全。

Session共享的解决方案_第2张图片

优点:

  • 代码灵活,基于分布式Redis,可以实现对高并发请求的支持。

缺点:

  • 需要修改的代码较多,涉及到Session的地方都需要更改。不太适合对老系统的改造,比较适合于新开发的系统。但是如果我们提前将用户接口抽离成了一个单独的服务,那么改造起来还是比较好处理的。

测试结果:

1.问题展示

我们先用第一台服务器访问用户数据,请求携带session的id从而后台进行查询,就可以得到用户的相关信息

Session共享的解决方案_第3张图片

这时候我们换第二三台服务器进行测试(第三台与第二台)

Session共享的解决方案_第4张图片

得到的结果都如下:

在这里插入图片描述

2.redis解决

使用服务器1访问用户信息:

Session共享的解决方案_第5张图片

使用服务器2访问用户信息:

Session共享的解决方案_第6张图片

使用服务器3访问用户信息:

Session共享的解决方案_第7张图片
使用redis实现了用户信息在tomcat集群中的共享

你可能感兴趣的:(java,服务器,tomcat,java)