基于Redis实现分布式Session(一)

2015-07-16 12:08:31 · 作者: · 浏览: 0

1、概述
我们可以自己实现类似Session的机制,采用 Redis 等分布式缓存中间件来实现。Redis是独立于应用服务器的,基于Redis实现的Session机制自动具备了分布式属性。Redis可以很方便地做集群配置,则Session避免了单点故障。


2、实现
实现代码极其简单,如下所示。


/**
?* @author liuhailong2008#foxmail
?*/
public class ApiSession implements Serializable {


? ? private static final long serialVersionUID = 1055965810150154404L;


? ? /**Session ID*/
? ? private final String? ? ? ? ? ? ? id;
? ? /**Session创建时间*/
? ? private long? ? ? ? ? ? ? ? creationTime;
? ? /**Session最后一次访问时间*/
? ? private long? ? ? ? ? ? ? ? lastAccessedTime;
? ? /**Session的最大空闲时间间隔*/
? ? private int? ? ? ? ? ? ? ? maxInactiveInterval;
? ? /**是否是新建Session*/
? ? private boolean? ? ? ? ? ? newSession;


? ? private static final String SESSION_KEY_PREFIX = "SESS_";
? ? //private Set attrNameSet = Collections.synchronizedSet(new HashSet());
? ? private final String sessionKey ;


? ? /**
? ? * 创建新的Session。
? ? * @param maxIdleSeconds
? ? */
? ? public ApiSession(int maxIdleSeconds){
? ? ? ? id = StringUtil.getUUID();
? ? ? ? long now = System.currentTimeMillis();
? ? ? ? creationTime = now;
? ? ? ? lastAccessedTime = now;
? ? ? ? this.maxInactiveInterval = maxIdleSeconds;
? ? ? ? newSession = true;
? ? ? ? //this.attrNameSet.clear();


? ? ? ? sessionKey = SESSION_KEY_PREFIX + id;
? ? ? ? CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX);
? ? ? ? CacheElement ce = new CacheElement(sessionKey,this);
? ? ? ? ce.setTimeToIdleSeconds(this.getMaxInactiveInterval());
? ? ? ? cb.put(ce);
? ? }


? ? /**
? ? * 通过Session id获取已经存在的Session,如果没有,返回null。
? ? * @return
? ? */
? ? public static ApiSession get(String id){
? ? ? ? String sessionKey = SESSION_KEY_PREFIX + id;
? ? ? ? CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX);
? ? ? ? ApiSession ret = (ApiSession) cb.get(sessionKey);
? ? ? ? if(ret!=null){
? ? ? ? ? ? ret.newSession = false;
? ? ? ? ? ? ret.refresh();
? ? ? ? }
? ? ? ? return ret;
? ? }
? ? /**
? ? * 更新 lastAccessedTime 。
? ? */
? ? public void refresh() {
? ? ? ? this.lastAccessedTime = System.currentTimeMillis();
? ? ? ? CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX);
? ? ? ? CacheElement ce = new CacheElement(sessionKey,this);
? ? ? ? ce.setTimeToIdleSeconds(this.getMaxInactiveInterval());
? ? ? ? cb.put(ce);
? ? }
? ? /**
? ? * 是否超时过期。
? ? *
? ? * @param session
? ? * @return
? ? */
? ? public boolean isExpired() {
? ? ? ? CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX);
? ? ? ? ApiSession _this = (ApiSession) cb.get(this.sessionKey);
? ? ? ? // 先查看缓存层面的超时控制
? ? ? ? if(_this==null){
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? long now = System.currentTimeMillis();
? ? ? ? long last = this.getLastAccessedTime();
? ? ? ? long interal = now - last;
? ? ? ? if(interal>this.getMaxInactiveInterval()){
? ? ? ? ? ? this.invalidate();
? ? ? ? ? ? return true;
? ? ? ? }else{
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
? ? /**
? ? * 强制Session立即失效。
? ? */
? ? public synchronized void invalidate() {
? ? ? ? CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX);
? ? ? ? cb.remove(this.sessionKey);
? ? }


? ? /**
? ? * 移除属性。
? ? *
? ? * @param attrName
? ? * @return
? ? */
? ? public synchronized Object removeAttribute(String attrName){
? ? ? ? this.refresh();
? ? ? ? String attrSessionKey = getAttrSessionKey(attrName);
? ? ? ? CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX);
? ? ? ? Object ret = cb.remove(attrSessionKey);
? ? ? ? return ret;
? ? }


? ? /**
? ? * 设置属性。
? ? * @param attrName
? ? * @param attrValue
? ? */
? ? public synchronized void setAttribute(String attrName,Object attrValue){
? ? ? ? this.refresh();
? ? ? ? String attrSessionKey = getAttrSessionKey(at