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
那JedisCluster的连接池呢?有没有JedisClusterPool?答案是没有。
为啥没有?
因为JedisCluster内部就有池的实现。同时JedisCluser的get/set/exist都是使用的模板模式,connection是共用的。如果还不清楚,那就去看源码
参见
这篇博客里说的
tomcat-redis-session-manager
里面使用的Jedis!
那么如果我使用的RedisCluster的集群模式
改动tomcat的context.xml,如下:(同时那几个jar包也得放进去,参见之前的
单redis与tomcat整合)
会如何呢?
会报这个错误:
这个错误是什么意思?
你用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"%>
SessionID:<%=session.getId()%>