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整合比较简单
见下文
http://blog.csdn.net/qq584852076/article/details/46502185


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


OK,在这篇博客里
我用了一个nginx,版本号1.10.2
2个tomcat,版本号都是7.0.68
6个Redis实例构成的RedisCluster,版本号是3.2.0。集群的模式,就是官方推出的Cluster,key在服务器端分流。关于redis集群的构建,大家可以参考 http://blog.csdn.net/xu470438000/article/details/42971091
我当时在搭建redis集群的时候,碰到的最大的问题就是关于ruby组件的使用。
太tm丢人了。
当时总是出现./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)
后来误打误撞解决了问题。
似乎当时使用了rvm选择了默认的ruby版本才OK的
参见: https://my.oschina.net/junfrost/blog/143487


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<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
        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是共用的。如果还不清楚,那就去看源码
参见 http://brandnewuser.iteye.com/blog/2312071


大家明白了么?
我们按照 http://blog.csdn.net/qq584852076/article/details/46502185 这篇博客里说的
tomcat-redis-session-manager
里面使用的Jedis!
那么如果我使用的RedisCluster的集群模式
改动tomcat的context.xml,如下:(同时那几个jar包也得放进去,参见之前的 单redis与tomcat整合)
<?xml version='1.0' encoding='utf-8'?>  
<Context>  
    <WatchedResource>WEB-INF/web.xml</WatchedResource>  
      
    <!-- tomcat-redis-session共享配置 -->  
    <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />  
        <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"  
         host="localhost"   
         port="6379"   
         database="0"   
         maxInactiveInterval="60" />  
<!----------------------------- -->  
</Context>  
会如何呢?
会报这个错误:



这个错误是什么意思?
你用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即可
但是具体要改的的地方还不少,代码我就不贴上来了,具体见:
https://github.com/cxyxd/tomcat-redis-session-manager/blob/master/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java


这个项目用的别的组件如下:
  compile 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包在哪么?

http://pan.baidu.com/s/1dEZZFmp
本来想直接上传到csdn的资源栏目的,不过传了几次都是错误。


好的我们看看效果

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
/usr/local/tomcat7_forZW/webapps/PathTest--8080
<br>
SessionID:<%=session.getId()%>
</body>
</html>
我们在两个tomcat下都放一个sessiontest.jsp,内容如上

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

我们访问一下:

换个地址,结果如下:

我们再去看看redis里面





参考资料
jredis cluster客户端使用
JedisCluster中应用的Apache Commons Pool对象池技术
tomcat7 redis session 共享
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值