redis+tomcat实现session共享

session共享

    如果在实际应用部署中,只部署单台tomcat,那么不需要考虑session共享,因为无论怎么访问,session肯定来自tomcat部署的这台机器上,当我们的应用需要两个或者两个以上的tomcat服务器来支撑时,就需要考虑session共享的问题了,如果不考虑,假设用户在一台tomcat的应用上登录了,如果负载均衡让我们的访问出现在了另外的一台机器上,那么由于这两台机器并没有做session共享,就需要用户再次登录,这就造成很不友好的用户体验。

    session共享的方案有多种,有基于memcached,redis的实现方式,也可以让两台服务器上存储session的位置做文件同步,这样session也可以是一致的,但是会有延时的问题,无论哪种实现方式,他们的原理都相同。即将用户登录的session保存在同一个地方,无论用户最终访问的是哪一个tomcat服务器,都会保证session一致。

   这里介绍tomcat+redis实现session共享:需要两个tomcat,一个redis服务器即可。tomcat可以部署在不同的虚拟机,也可以部署在同一台机器(开启不同的端口)。

具体实施

1、并没有什么官方给出tomcat集群session共享方案的redis实现,但是github上有人实现了tomcat基于redis的session共享。

2、代码中并没有直接支持tomcat8,但是给出了支持tomcat8的修改方法。

具体修改代码:RedisSessionManager.java,修改方法initializeSerializer中的如下部分:

3、自己编译项目打包tomcat-redis-session-manager.jar

     可以按照github例子,构建gradle项目,引入commons-pool2-2.3.jar和jedis-2.7.2.jar,tomcat-catalina-8.0.14.jar即可。

    

   最后在项目目录下运行:gradle build即可,构建成功之后,在build/libs目录下会生成tomcat-redis-session-manager.jar。将生成的jar以及commons-pool2-2.3.jar、jedis-2.7.2.jar加入到tomcat/lib目录下。

   也可以构建maven项目引入commons-pool2,jedis依赖,修改代码之后,就可以打包。

4、修改tomcat/conf/context.xml配置文件增加Valve,Manager配置。

在context.xml的Context节点下增加如下配置:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/>
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
    host="127.0.0.1"
    port="6379"
    database="0"
    maxInactiveInterval="60"
    />

注意细节

1、修改context.xml配置文件时需要注意Valve不要写成Value,否则会报错,另外类的名字也是RedisSessionHandlerValve。

10-Sep-2018 20:20:59.747 WARNING [localhost-startStop-1] org.apache.tomcat.util.digester.Digester.endElement   No rules found matching 'Context/Value'.
10-Sep-2018 20:20:59.996 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal The session manager failed to start
 org.apache.catalina.LifecycleException: Failed to start component [com.orangefunction.tomcat.redissessions.RedisSessionManager[]]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5380)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:755)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:731)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1125)
        at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1868)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

2、一定要将Valve配置在Manager之前。

测试

这里我将两个tomcat部署在一个虚拟机上,分别开启端口8080和8090。

编写session测试文件:

webapps/ROOT/session.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<BR>
SessionID:<%=session.getId()%>
<BR>
SessionIP:<%=request.getServerName()%>
<BR>
SessionPort:<%=request.getServerPort()%>
<BR>

重启tomcat,在一个浏览器中开启两个tab页,分别访问

http://10.119.9.149:8080/session.jsp

http://10.119.9.149:8090/session.jsp

虽然是访问的两个tomcat,但是他们返回的session却是一致的。这说明session共享已经实现。

我们可以访问redis,看看页面上的sessionid :5DF9262B7C7A929AD081F2F8D4A6A828 保存情况。 

[root@server tomcat8080]# /usr/local/bin/redis-cli
127.0.0.1:6379> dbsize
(integer) 1
127.0.0.1:6379> keys *
1) "5DF9262B7C7A929AD081F2F8D4A6A828"
127.0.0.1:6379> get 5DF9262B7C7A929AD081F2F8D4A6A828
"\xac\xed\x00\x05sr\x00Dcom.orangefunction.tomcat.redissessions.SessionSerializationMetadata\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x01[\x00\x15sessionAttributesHasht\x00\x02[Bxpw\x14\x00\x00\x00\x10\x1c\x1f\xd4\xa1k\x1aq\xd3u\xfbe\xbffJ\x8c\xabxsr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01e\xc6\x9d\xed#sq\x00~\x00\x03\x00\x00\x01e\xc6\x9d\xed#sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexq\x00~\x00\x04\x00\x00\a\bsr\x00\x11java.lang.Boolean\xcd r\x80\xd5\x9c\xfa\xee\x02\x00\x01Z\x00\x05valuexp\x01q\x00~\x00\nsq\x00~\x00\x03\x00\x00\x01e\xc6\x9d\xed#t\x00 5DF9262B7C7A929AD081F2F8D4A6A828sq\x00~\x00\a\x00\x00\x00\x00w\b\x00\x00\x01e\xc6\x9d\xed#"
127.0.0.1:6379> 

至此,tomcat+redis session共享方案已经试验完成,需要注意的是配置context.xml文件时,一定要注意不要把Valve写成了Value。避免造成不必要的麻烦。

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值