RedisCluser(v-3.2.0)与Tomcat7的Session整合

网友投稿 628 2022-11-26

RedisCluser(v-3.2.0)与Tomcat7的Session整合

RedisCluser(v-3.2.0)与Tomcat7的Session整合

一般情况下,一个web系统的架构是类似这样的:

一个或多个nginx做负载均衡,后面连多个tomcat(或别的类型的web服务器)。

nginx做负载的时候,关于request的分流,至少就有两种策略,第一种就是根据请求的ip做hash,这样能保证同一个ip的请求都映射到同一个tomcat上。第二种,就是直接按照时间或者后端服务器的性能,负载等条件进行分流,那么这样,比如就会产生session问题。

所以一般的web系统,会把用户的session单独放到一个服务器上,业内大多使用Redis来存储用户session。

这种架构,后端可以使用一个redis实例,也可以使用多个redis实例。

如果是单redis的话,与tomcat整合比较简单

但是,如果只有一个redis,总感觉有点不安全,我们可以使用多个redis。

一般的架构如图:

OK,在这篇博客里

我用了一个nginx,版本号1.10.2

2个tomcat,版本号都是7.0.68

6个Redis实例构成的RedisCluster,版本号是3.2.0。集群的模式,就是官方推出的Cluster,key在服务器端分流。关于redis集群的构建,大家可以参考

我当时在搭建redis集群的时候,碰到的最大的问题就是关于ruby组件的使用。

太tm丢人了。

当时总是出现./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)

后来误打误撞解决了问题。

似乎当时使用了rvm选择了默认的ruby版本才OK的

OK,行文到此,我默认大家目前都已经把nginx和redis集群都搭建好了(其实这篇文章里面的技术和nginx没关系)

那么单redis和rediscluster的使用有什么区别么?

单redis的java客户端使用的是jedis,例子如下:

Jedis jedis=new Jedis("192.168.0.100", 6379); jedis.set("name","xinxin");

如果是使用JedisPool那后面就要close一下,差别不大

RedisCluster的java客户端使用的不是jedis而是JedisCluster,例子如下:

String key = "2"; // 这东西 可以直接看到key 的分片数,就能知道放哪个 节点 System.out.println(JedisClusterCRC16.getSlot(key)); Set jedisClusterNodes = new HashSet(); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7002)); // 3个master 节点 JedisCluster jc = new JedisCluster(jedisClusterNodes); System.out.println(jc.get(key)); jc.setnx(key, "bar"); String value = jc.get(key); System.out.println(value);

那JedisCluster的连接池呢?有没有JedisClusterPool?答案是没有。

为啥没有?

因为JedisCluster内部就有池的实现。同时JedisCluser的get/set/exist都是使用的模板模式,connection是共用的。如果还不清楚,那就去看源码

参见

​​ 这篇博客里说的

tomcat-redis-session-manager

里面使用的Jedis!

那么如果我使用的RedisCluster的集群模式

改动tomcat的context.xml,如下:(同时那几个jar包也得放进去,参见之前的

​​ 单redis与tomcat整合​​)

WEB-INF/web.xml

会如何呢?

会报这个错误:

这个错误是什么意思?

你用jedis去连接RedisCluster还问我为什么!!!-

那咋办?改呗。改什么?改tomcat-redis-session-manager的源码呗。

我们根据上面那个错误,可以看到问题发生在RedisSessionManager的loadSessionDataFromRedis方法

源码如下:

//RedisSessionManager.java public byte[] loadSessionDataFromRedis(String id) throws IOException { Jedis jedis = null; Boolean error = true; try { log.trace("Attempting to load session " + id + " from Redis"); jedis = acquireConnection(); byte[] data = jedis.get(id.getBytes()); error = false; if (data == null) { log.trace("Session " + id + " not found in Redis"); } return data; } finally { if (jedis != null) { returnConnection(jedis, error); } } }

看到了吧,使用的是jedis。

那既然知道问题了,那就好改了

大体的说:把Jedis改成JedisCluster即可

但是具体要改的的地方还不少,代码我就不贴上来了,具体见:

​​group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '7.0.68' compile group: 'redis.clients', name: 'jedis', version: '2.8.2' compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.4.2'

我靠你说了半天,整合rediscluster(v-3.2.0)与tomcat7的最主要的jar包在哪么?

​​page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>Insert title here/usr/local/tomcat7_forZW/webapps/PathTest--8080
SessionID:<%=session.getId()%>

我们在两个tomcat下都放一个sessiontest.jsp,内容如上

/usr/local/tomcat7_forZW/webapps/PathTest--8080这是tomcat的地址与端口号,两个jsp的这部分内容不一样(一个端口是,8080一个是1314)

我们访问一下:

换个地址,结果如下:

我们再去看看redis里面

参考资料

​​jredis cluster客户端使用​​

​​JedisCluster中应用的Apache Commons Pool对象池技术​​

​​tomcat7 redis session 共享​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot使用H2嵌入式数据库的实例代码
下一篇:ShardedJedis的一致性hash
相关文章

 发表评论

暂时没有评论,来抢沙发吧~