session共享

多台tomcat 集群的时候 要么ip访问固定指向服务器 要么就只能共享session了
集群 

 upstream web_tomcats {
        ip_hash;//  ip访问固定指向服务器
server 127.0.0.1:7201 weight=10;
server 127.0.0.1:7202 weight=10;
 
这里 讲共享session  
我们用redis    启动server   ./src/redis-server redis.conf
 redis.conf设置下密码  别让谁都能来玩 
找到#  requirepass 去掉#号  requirepass 后面设置密码
可以启动cli 测试一下
./src/redis-cli 不输入密码
./src/redis-cli -a mima 和输入密码
测试语句  set chen haha

然后spring 配置
<!--jedis pool配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
<property name="maxWait" value="10" />
<property name="testOnBorrow" value="true" />
</bean>
<!-- jedis pool配置 -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1" value="${Jedis.url}" /> 这个就是ip地址  不要输入http://什么的
<constructor-arg index="2" value="6379" /> 这个是端口号
<constructor-arg index="3" value="3000" /> 这个我也不知道
<constructor-arg index="4" value="${Jedis.pwd}" />
</bean>

pom.xml配置  导个包
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.0.0</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>  
然后写个redis的 service封装一些方法  这里的封装来源宋哥 哈哈

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;

/**
 * Redis封装模板及通用方法; 
 * /usr/local/bin/redis-server /etc/redis/6380.conf
 * @author wei
 * 
 */
@Service
public class RedisCacheService {
  Logger logger = Logger.getLogger(RedisCacheService.class);
  
  /**
   * 数据源
   */
  @Autowired private JedisPool jedisPool;

  /**
   * 获取自增id,正整数long 用于jpushsendNo. 
   * 改用redis自身DB支持,不访问数据库
   * 
   * @param  name   业务id, 目前可以使用"jpush","chat_room"
   * @return long 
   */
  public synchronized long getUniqNoSequency(String name){
    return  incr(name + "sequency");
  }


  /**
   *  用户未读信息计数(消息、分享。。一切推送的消息)
   * @param userId 
   * @param reset  清零标记, ture-归零;  默认false
   * @return  0--n  
   */
  public long getMessageCounter(long userId,boolean reset){
    String key= "unreadMessage-"+userId;
    //获取缓存里面的数据
    if(reset){
      del(key);
      return 0;
    }else {
      Long incr = incr(key);
      return incr==null ? 0 : incr;
    }
  }
  

  /******************  下面开始是模板方法! 上面定义公共函数  ***************************************************/  
  
  /**
   * 执行有返回结果的action。
   */
  protected <T> T execute(JedisAction<T> jedisAction) throws JedisException {
    Jedis jedis = null;
    boolean broken = false;
    try {
      jedis = jedisPool.getResource();
      return jedisAction.action(jedis);
    } catch (JedisConnectionException e) {
      logger.error("Redis connection lost.", e);
      broken = true;
      throw e;
    } finally {
      closeResource(jedis, broken);
    }
  }

  /**
   * 执行无返回结果的action。
   */
  protected void execute(JedisActionNoResult jedisAction) throws JedisException {
    Jedis jedis = null;
    boolean broken = false;
    try {
      jedis = jedisPool.getResource();
      jedisAction.action(jedis);
    } catch (JedisConnectionException e) {
      logger.error("Redis connection lost.", e);
      broken = true;
      throw e;
    } finally {
      closeResource(jedis, broken);
    }
  }

  /**
   * 根据连接是否已中断的标志,分别调用returnBrokenResource或returnResource。
   */
  protected void closeResource(Jedis jedis, boolean connectionBroken) {
    if (jedis != null) {
      try {
        if (connectionBroken) {
          jedisPool.returnBrokenResource(jedis);
        } else {
          jedisPool.returnResource(jedis);
        }
      } catch (Exception e) {
        logger.error("Error happen when return jedis to pool, try to close it directly.", e);
        closeJedis(jedis);
      }
    }
  }

  /**
   * 获取内部的pool做进一步的动作。
   */
  public JedisPool getJedisPool() {
    return jedisPool;
  }

  /**
   * 有返回结果的回调接口定义。
   */
  public interface JedisAction<T> {
    T action(Jedis jedis);
  }

  /**
   * 无返回结果的回调接口定义。
   */
  public interface JedisActionNoResult {
    void action(Jedis jedis);
  }

  // // 常用方法的封装 / //

  // // 公共 ///
  /**
   * 删除key, 如果key存在返回true, 否则返回false。
   */
  public boolean del(final String key) {
    return execute(new JedisAction<Boolean>() {

      @Override
      public Boolean action(Jedis jedis) {
        return jedis.del(key) == 1 ? true : false;
      }
    });
  }

  public void flushDB() {
    execute(new JedisActionNoResult() {

      @Override
      public void action(Jedis jedis) {
        jedis.flushDB();
      }
    });
  }

  // // 关于String ///
  /**
   * 如果key不存在, 返回null.
   */
  public String get(final String key) {
    return execute(new JedisAction<String>() {

      @Override
      public String action(Jedis jedis) {
        return jedis.get(key);
      }
    });
  }

  /**
   * 如果key不存在, 返回0.
   */
  public Long getAsLong(final String key) {
    String result = get(key);
    return result != null ? Long.valueOf(result) : 0;
  }

  /**
   * 如果key不存在, 返回0.
   */
  public Integer getAsInt(final String key) {
    String result = get(key);
    return result != null ? Integer.valueOf(result) : 0;
  }

  public void set(final String key, final String value) {
    execute(new JedisActionNoResult() {

      @Override
      public void action(Jedis jedis) {
        jedis.set(key, value);
      }
    });
  }

  public void setex(final String key, final int seconds, final String value) {
    execute(new JedisActionNoResult() {

      @Override
      public void action(Jedis jedis) {
        jedis.setex(key, seconds, value);
      }
    });
  }

  /**
   * 如果key还不存在则进行设置,返回true,否则返回false.
   */
  public boolean setnx(final String key, final String value) {
    return execute(new JedisAction<Boolean>() {

      @Override
      public Boolean action(Jedis jedis) {
        return jedis.setnx(key, value) == 1 ? true : false;
      }
    });
  }

  public Long incr(final String key) {
    return execute(new JedisAction<Long>() {

      @Override
      public Long action(Jedis jedis) {
        return jedis.incr(key);
      }
    });
  }

  public Long decr(final String key) {
    return execute(new JedisAction<Long>() {

      @Override
      public Long action(Jedis jedis) {
        return jedis.decr(key);
      }
    });
  }

  // // 关于List ///
  public void lpush(final String key, final String value) {
    execute(new JedisActionNoResult() {

      @Override
      public void action(Jedis jedis) {
        jedis.lpush(key, value);
      }
    });
  }

  /**
     * Return the length of the list stored at the specified key. If the key
     * does not exist zero is returned (the same behaviour as for empty lists).
     * If the value stored at key is not a list an error is returned.
   */
  public long llen(final String key) {
    return execute(new JedisAction<Long>() {

      @Override
      public Long action(Jedis jedis) {
        return jedis.llen(key);
      }
    });
  }

  /**
   * 删除List中的第一个等于value的元素,value不存在或key不存在时返回0.
   */
  public boolean lremOne(final String key, final String value) {
    return execute(new JedisAction<Boolean>() {
      @Override
      public Boolean action(Jedis jedis) {
        Long count = jedis.lrem(key, 1, value);
        return (count == 1);
      }
    });
  }

  /**
     * Return the specified elements of the list stored at the specified key.
     * Start and end are zero-based indexes. 0 is the first element of the list
     * (the list head), 1 the next element and so on.
   */
  public List<String> lrange(final String key, final long start, final long end) {
    return execute(new JedisAction<List<String>>() {
      @Override
      public List<String> action(Jedis jedis) {
        return jedis.lrange(key, start, end);
      }
    });

  }

  /**
   * 删除List中的所有等于value的元素,value不存在或key不存在时返回0.
   */
  public boolean lremAll(final String key, final String value) {
    return execute(new JedisAction<Boolean>() {
      @Override
      public Boolean action(Jedis jedis) {
        Long count = jedis.lrem(key, 0, value);
        return (count > 0);
      }
    });
  } 
  
  
  // // 关于Sorted Set ///
  /**
   * 加入Sorted set, 如果member在Set里已存在,只更新score并返回false,否则返回true.
   */
  public boolean zadd(final String key, final String member, final double score) {
    return execute(new JedisAction<Boolean>() {

      @Override
      public Boolean action(Jedis jedis) {
        return jedis.zadd(key, score, member) == 1 ? true : false;
      }
    });
  }

  /**
   * 删除sorted set中的元素,成功删除返回true,key或member不存在返回false。
   */
  public boolean zrem(final String key, final String member) {
    return execute(new JedisAction<Boolean>() {

      @Override
      public Boolean action(Jedis jedis) {
        return jedis.zrem(key, member) == 1 ? true : false;
      }
    });
  }

  /**
   * 返回List长度, key不存在时返回0,key类型不是sorted set时抛出异常.
   */
  public long zcard(final String key) {
    return execute(new JedisAction<Long>() {

      @Override
      public Long action(Jedis jedis) {
        return jedis.zcard(key);
      }
    });
  }

  /**
   * Set a timeout on the specified key
   * @param key
   * @param seconds
   */
  public void expire(final String key, final int seconds) {
    execute(new JedisActionNoResult() {
      @Override
      public void action(Jedis jedis) {
        jedis.expire(key, seconds);
      }
    });
  }
  
  public boolean exists(final String key) {
    return execute(new JedisAction<Boolean>() {
      @Override
      public Boolean action(Jedis jedis) {
        return jedis.exists(key);
      }
    });
  }
  
  
  /**
   * 退出然后关闭Jedis连接。
   */
  public static void closeJedis(Jedis jedis) {
    if (jedis.isConnected()) {
      try {
        try {
          jedis.quit();
        } catch (Exception e) {
        }
        jedis.disconnect();
      } catch (Exception e) {

      }
    }
  } 

}

最后就是一些思路上的问题了
  用户登录 发送请求 登录成功 生成一个32位的MD5字符戳 和用户对象 User
把他当做key value存在redis里面 User弄成json字符串  
比如说 

redisCacheService.setex(sessionid, 60*120, new Gson().toJson(user)); //
60*120这个是60秒*120  120分钟啦

String cache= redisCacheService.get(token);
 user=new Gson().fromJson(cache, User.class); 

生成的 MD5字符串传回给用户   浏览器存到cookie里面去  每个请求都会自动带cookie来的 嘿嘿 
每次取cache不为null的时候 就再写入一遍  不然过期了 你负责啊
然后基本就成功了




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值