基于Redis实现分布式Session
来源:互联网 发布:康辉旅游网站源码 编辑:程序博客网 时间:2024/05/16 23:34
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<String> attrNameSet = Collections.synchronizedSet(new HashSet<String>()); 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(attrName); CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX); CacheElement ce = new CacheElement(attrSessionKey,attrValue); ce.setTimeToIdleSeconds(this.getMaxInactiveInterval()); cb.put(ce); } /** * 获取属性的值。 * @param attrName * @return */ public Object getAttribute(String attrName){ this.refresh(); String attrSessionKey = getAttrSessionKey(attrName); CacheBlock cb = CacheManager.getBlock(Const.CACHE_BLOCK_INDEX); Object retObject = cb.get(attrSessionKey); return retObject; } private String getAttrSessionKey(String attrName){ String attrSessionKey = sessionKey + attrName; return attrSessionKey; } public int getMaxInactiveInterval() { if(maxInactiveInterval==-1){ maxInactiveInterval = 3600; } return maxInactiveInterval; } public void setMaxInactiveInterval(int maxInactiveInterval) { this.maxInactiveInterval = maxInactiveInterval; } public String getId() { return id; } public long getCreationTime() { return creationTime; } public long getLastAccessedTime() { return lastAccessedTime; } public boolean isNewSession() { return newSession; }}
3、用法
3.1、建立Session
// 建立Sessionint maxIdleSeconds = 60 * 20 ;ApiSession session = new ApiSession( maxIdleSeconds );String sessId = session.getId();session.setAttribute("CURRENT_USER", user);
3.2、读取Session
// 读取SessionApiSession session = ApiSession.get(tokenToBeChecked);if(session==null){ logger.debug(String.format("会话超时啦,token:%s。", tokenToBeChecked)); return false;}// 检查是否超时boolean isExpired = session.isExpired();if(isExpired){ logger.debug(String.format("会话超时啦,token:%s。", tokenToBeChecked)); return false;}// 从Sesion中取出tokenString token = (String)session.getAttribute(Const.TOKEN_SESSION_KEY);if(StringUtils.isEmpty(token)){ return false;}// 同调用方提交的比较if(token.equalsIgnoreCase(tokenToBeChecked)){ session.refresh(); return true;}
4、优化点
以上只是提供了实现范例。进一步的优化点包括:
- Redis存储规划,设计Session Id 、Attr的存储方式。
- 采用自己的持久化方式,提高持久化效率。
- 提供更多工具方法,让Session更易用。
- 进一步实现Session的其他接口。
等等。
未尽事宜,欢迎留言讨论。
0 1
- 基于Redis实现分布式Session
- 分布式Session:基于Spring-Session 和 Redis实现
- C# 基于StackExchange.Redis.dll利用Redis实现分布式Session
- redis实现分布式session共享
- redis实现分布式session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Redis SpringSession+Redis实现分布式Session存储
- 分布式应用session会话管理-基于redis
- 【hive内置基本数据类型】 和 【内置复合数据类型用法】
- iOS开发笔记10--App store最新审核标准(2015.3)公布
- 使用Auto Layout导致调用addSubView时出现的问题
- 我叫许大方
- 如何做一个简单的开放接口(4)-常见Handler的参考实现
- 基于Redis实现分布式Session
- Debian用apt-get 安装软件时出现的问题!
- 黑马程序员_Java基础(方法,数组)
- FCkEditor编辑器漏洞(IIS 6.0)
- 模版方法模式
- 题目2:MySQL----------Second Highest Salary
- 《Java程序设计》第二次作业:MySQL数据库及Java操作MySQL数据库
- 开放接口平台 in Action(汇总目录)
- struts2配置详解