专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

集群session共享方案

在Web项目开发中,会话管理是一个很重要的部分,用于存储与用户相关的数据。通常是由符合session规范的容器来负责存储管理,也就是一旦容器关闭,重启会导致会话失效。因此打造一个高可用性的系统,必须将session管理从容器中独立出来。而这实现方案有很多种,下面简单介绍下(仅限目前自己已知的):

  第一种:使用硬件F5做粘性会话(不会,只是知道可以这么干),成本太高,后期也不好维护。

第二种:使用Nginx的ip_hash特性做粘性会话,可以让用户每次访问都转发到该用户第一次访问的web容器上,但是当该web容器上的应用挂了,nginx不会将该用户的请求转发到别的web容器,体验不好。

第三种:基于cookie实现,将session直接存储到cookie中(安全问题,虽然可以加密存储,但是觉得不能将敏感数据放在客户端)

第四种:使用容器扩展来实现,大家比较容易接受的是通过容器插件来实现,比如基于Tomcat的memcached-session-manager / tomcat-redis-session-manager,基于Jetty的jetty-nosql-memcache / jetty-session-redis等等。好处是对项目来说是透明的,无需改动代码。不过前者目前还不支持Tomcat 8,或者说不太完善。此方法过于依赖容器,一旦容器升级或者更换意味着又得从新来过。并且代码不在项目中,对开发者来说维护也是个问题(如果你使用的是weblogic、jboss、websphere等商业web容器,根本没有这种第三方容器扩展,web容器换了厂商就不行了)。

  第五种:自己实现一套会话管理,将session读取/存储到Redis或其他nosql或数据库(网站用户量大的情况下,频繁dml数据,对db压力大)中。很显然这个方案灵活性最大,但开发需要一些额外的时间。弄懂了会挺不错的。

  第六种:使用框架的会话管理工具spring-session,可以理解是替换了Servlet那一套会话管理,既不依赖容器,又不需要改动代码,并且是用了spring-data-redis那一套连接池,可以说是最完美的解决方案。当然,前提是项目要使用Spring Framework才行。

  第七种:如果项目中使用shiro这种自带session(非httpsession)的权限框架,需要重写shiro的SessionDao将session存入redis(或其他)来实现session共享,可以自己重写(也不是很麻烦)或者找现成的(shiro-redis微笑脸,省的自己造轮子了,知道原理就行)。

前三种方案:出于安全、成本(自己搞着玩不好弄)、无法完全做到724365不宕机,个人不推荐。有兴趣的自己研究吧。

剩下的四种方案大体思路其实都一样,存到nosql中(内存读写快啊)。

各方案具体实现思路:

第四种:

直接去这几个插件github地址,人家写的使用方法更全,不在赘述。(看了点redis-session-manager的源码,他是将自定义了一个RedisSession类继承StandardSession类,这个类是tomcat中lib下的类,太依赖容器了,获取session信息从redis中序列化/反序列化出来)

第五种:(参考别人博客,内容直接粘贴过来了,地址在最上面)

要实现将session信息存入redis,总结了下大概是三点: 1.实现httpsession接口,重写我们需要用到的方法,比如set get这些。。balabala一堆…… 2.继承HttpServletRequestWrapper,这个类里面有getSession()方法,我们需要重写,来取自定义session 3.实现filter,用来拦截客户端请求,获取我们自定义的request,从而获得session

具体实现(这个人并没有实现从redis中读取session的操作,需要将request中获取session和产生session都加入redis操作,但是这里的思路需要掌握,很受教,自己想要实现完美挺难的): 1.实现httpsession接口



1、 public class HttpSessionWrapper implements HttpSession {
2、 protected final Logger logger = LoggerFactory.getLogger(getClass());
3、 private String sid = "";
4、 private HttpServletRequest request;
5、 private HttpServletResponse response;
6、 private final long creationTime = System.currentTimeMillis();
7、 private final long lastAccessedTime = System.currentTimeMillis();
8、 private SessionMeta meta;
9、 public HttpSessionWrapper() {
10、 }
11、 public HttpSessionWrapper(String sid,SessionMeta meta, HttpServletRequest request,
12、 HttpServletResponse response) {
13、 this.sid=sid;
14、 this.request=request;
15、 this.response=response;
16、 this.meta=meta;
17、 }
18、 public Object getAttribute(String name) {
19、 logger.info(getClass()+"getAttribute(),name:"+name);
20、 Jedis jedis =null;
21、 Object obj =null;
22、 String jsonStr = null;
23、 try {
24、 jedis =JedisPoolStore.getInstance().getJedis(meta.getHost(), meta.getPort());
25、 jsonStr = jedis.get(name);
26、 if(jsonStr!=null||StringUtils.isNotEmpty(jsonStr)){
27、 jedis.expire(name, meta.getSeconds());// 重置过期时间
28、 obj =JSON.parseObject(jsonStr, User.class); //反序列对象
29、 }
30、 if (jedis != null) {
31、 JedisPoolStore.getInstance().returnJedis(jedis);
32、 }
33、 return obj;
34、 }
35、 catch (JSONException je) {
36、 logger.error(je.getMessage());
37、 if (null != jedis)
38、 JedisPoolStore.getInstance().returnJedis(jedis);
39、 return jsonStr;
40、 }
41、 catch (Exception e) {
42、 logger.error(e.getMessage());
43、 if (e instanceof JedisException) {
44、 if (null != jedis)
45、 JedisPoolStore.getInstance().returnBrokenJedis(jedis);
46、 } else {
47、 if (null != jedis)
48、 JedisPoolStore.getInstance().returnJedis(jedis);
49、 }
50、 throw new HttpSessionException(" session 异常 getAttribute() name:"+name);
51、 }
52、 }
53、 public void setAttribute(String name, Object value) {
54、 logger.info(getClass()+"setAttribute(),name:"+name);
55、 Jedis jedis =null;
56、 try {
57、 jedis =JedisPoolStore.getInstance().getJedis(meta.getHost(), meta.getPort());
58、 if(value instanceof String){
59、 String value_ =(String) value;
60、 jedis.set(name,value_);//普通字符串对象
61、 }else{
62、 jedis.set(name, JSON.toJSONString(value));//序列化对象
63、 }
64、
65、 jedis.expire(name, meta.getSeconds());// 重置过期时间
66、 if (jedis != null) {
67、 JedisPoolStore.getInstance().returnJedis(jedis);
68、 }
69、 } catch (Exception e) {
70、 logger.error(e.getMessage());
71、 if (e instanceof JedisException) {
72、 if (null != jedis)
73、 JedisPoolStore.getInstance().returnBrokenJedis(jedis);
74、 } else {
75、 if (null != jedis)
76、 JedisPoolStore.getInstance().returnJedis(jedis);
77、 }
78、 throw new HttpSessionException(" session 异常 setAttribute() name:"+name+",value:"+value);
79、 }
80、
81、 }
82、 /**
83、 * 不可用
84、 * @deprecated
85、 *
86、 */
87、 public void invalidate() {
88、 logger.info(getClass()+"invalidate()");
89、 }
90、
91、 public void removeAttribute(String name) {
92、 logger.info(getClass()+"removeAttribute(),name:"+name);
93、 if(StringUtils.isNotEmpty(name)){
94、 Jedis jedis =null;
95、 try {
96、 jedis =JedisPoolStore.getInstance().getJedis(meta.getHost(), meta.getPort());
97、 jedis.del(name);
98、 if (jedis != null) {
99、 JedisPoolStore.getInstance().returnJedis(jedis);
100、 }
101、 } catch (Exception e) {
102、 logger.error(e.getMessage());
103、 if (e instanceof JedisException) {
104、 if (null != jedis)
105、 JedisPoolStore.getInstance().returnBrokenJedis(jedis);
106、 } else {
107、 if (null != jedis)
108、 JedisPoolStore.getInstance().returnJedis(jedis);
109、 }
110、 throw new HttpSessionException(" session 异常 removeAttribute() name:"+name);
111、 }
112、 }
113、
114、 }
115、 /**
116、 * 不可用
117、 * @deprecated
118、 *
119、 */
120、 public Object getValue(String name) {
121、 return null;
122、 }
123、 /**
124、 * 不可用
125、 * @deprecated
126、 *
127、 */
128、 public Enumeration getAttributeNames() {
129、 return null;
130、
131、 }
132、 /**
133、 * 不可用
134、 * @deprecated
135、 *
136、 */
137、 public String[] getValueNames() {
138、 return null;
139、 }
140、 /**
141、 * 不可用
142、 * @deprecated
143、 *
144、 */
145、 public void putValue(String name, Object value) {
146、 }
147、 /**
148、 * 不可用
149、 * @deprecated
150、 *
151、 */
152、 public void removeValue(String name) {
153、 }
154、
155、 public long getCreationTime() {
156、 return creationTime;
157、 }
158、
159、 public String getId() {
160、 logger.info(getClass()+"getId():"+sid);
161、 return sid;
162、 }
163、
164、 public long getLastAccessedTime() {
165、 return lastAccessedTime;
166、 }
167、 /**
168、 * 不可用
169、 * @deprecated
170、 *
171、 */
172、 public ServletContext getServletContext() {
173、 return null;
174、 }
175、 /**
176、 * 不可用
177、 * @deprecated
178、 *
179、 */
180、 public void setMaxInactiveInterval(int interval) {
181、 }
182、 /**
183、 * 不可用
184、 * @deprecated
185、 *
186、 */
187、 public int getMaxInactiveInterval() {
188、 return 0;
189、 }
190、 /**
191、 * 不可用
192、 * @deprecated
193、 *
194、 */
195、 public HttpSessionContext getSessionContext() {
196、 return null;
197、 }
198、 /**
199、 * 不可用
200、 * @deprecated
201、 *
202、 */
203、 public boolean isNew() {
204、 logger.info(getClass()+"isNew()");
205、 return false;
206、 }
207、 }

2、继承HttpServletRequestWrapper



1、 /***
2、 *
3、 * @author xiaoshuai
4、 *
5、 */
6、 public class DefinedHttpServletRequestWrapper extends HttpServletRequestWrapper{
7、 protected final Logger logger = LoggerFactory.getLogger(getClass());
8、
9、 private HttpSessionWrapper currentSession;
10、 private HttpServletRequest request;
11、 private HttpServletResponse response;
12、 private String sid = "";
13、 private SessionMeta meta;
14、
15、 public DefinedHttpServletRequestWrapper(HttpServletRequest request) {
16、 super(request);
17、 }
18、
19、 public DefinedHttpServletRequestWrapper(String sid, HttpServletRequest request) {
20、 super(request);
21、 this.sid = sid;
22、 }
23、
24、 public DefinedHttpServletRequestWrapper(String sid, SessionMeta meta,HttpServletRequest request,
25、 HttpServletResponse response) {
26、 super(request);
27、 this.request = request;
28、 this.response = response;
29、 this.sid = sid;
30、 this.meta=meta;
31、 }
32、
33、 @Override
34、 public HttpSession getSession(boolean create) {
35、 if(currentSession != null) {
36、 return currentSession;
37、 }
38、 if(!create) {
39、 return null;
40、 }
41、 currentSession = new HttpSessionWrapper(sid,meta, request, response);
42、 return currentSession;
43、 }
44、
45、 @Override
46、 public HttpSession getSession() {
47、 return getSession(true);
48、 }
49、
50、 }

3、实现filter



1、 public class SessionFilter implements Filter{
2、 protected final Logger logger = LoggerFactory.getLogger(getClass());
3、 private static SessionMeta meta = new SessionMeta();
4、 private static final String host ="host";
5、 private static final String port ="port";
6、 private static final String seconds="seconds";
7、
8、 public void init(FilterConfig filterConfig) throws ServletException {
9、 logger.debug("init filterConfig info");
10、 meta.setHost(filterConfig.getInitParameter(host));
11、 meta.setPort(Integer.parseInt(filterConfig.getInitParameter(port)));
12、 meta.setSeconds(Integer.parseInt(filterConfig.getInitParameter(seconds)));
13、 }
14、
15、 public void doFilter(ServletRequest request, ServletResponse response,
16、 FilterChain chain) throws IOException, ServletException {
17、 //从cookie中获取sessionId,如果此次请求没有sessionId,重写为这次请求设置一个sessionId
18、 HttpServletRequest httpRequest = (HttpServletRequest) request;
19、 HttpServletResponse httpResponse = (HttpServletResponse) response;
20、 String sid = CookieHelper.findCookieInfo(httpRequest,CookieHelper.COOKIE_DOMAIN_NAME);
21、 if(StringUtils.isEmpty(sid) ){
22、 try {
23、 sid =CookieHelper.saveCookie(SessionId.doIds(), httpResponse);
24、 } catch (Exception e) {
25、 e.printStackTrace();
26、 }
27、 }
28、 logger.info("JESSIONID:"+sid);
29、 chain.doFilter(new DefinedHttpServletRequestWrapper(sid,meta,httpRequest, httpResponse), response);
30、 }
31、
32、 public void destroy() {
33、 }
34、
35、 }

4、配置web.xml



1、 <!-- session过滤器 -->
2、 <filter>
3、 <filter-name>sessionFilter</filter-name>
4、 <filter-class>cn.session.filter.SessionFilter</filter-class>
5、 <init-param>
6、 <param-name>host</param-name>
7、 <param-value>10.1.193.1</param-value>
8、 </init-param>
9、 <init-param>
10、 <param-name>port</param-name>
11、 <param-value>6372</param-value>
12、 </init-param>
13、 <init-param>
14、 <param-name>seconds</param-name>
15、 <param-value>1800</param-value>
16、 </init-param>
17、 </filter>
18、 <filter-mapping>
19、 <filter-name>sessionFilter</filter-name>
20、 <url-pattern>/*</url-pattern>
21、 </filter-mapping>

第六种:(没用过,感觉这个人的挺靠谱,直接粘贴过来了,参考博客的地址也在最上面)



1、 这里简单记录下整合的过程:
2、 如果项目之前没有整合过spring-data-redis的话,这一步需要先做,在maven中添加这两个依赖:
3、 <dependency>
4、 <groupId>org.springframework.data</groupId>
5、 <artifactId>spring-data-redis</artifactId>
6、 <version>1.5.2.RELEASE</version>
7、 </dependency>
8、 <dependency>
9、 <groupId>org.springframework.session</groupId>
10、 <artifactId>spring-session</artifactId>
11、 <version>1.0.2.RELEASE</version>
12、 </dependency>
13、 再在applicationContext.xml中添加以下bean,用于定义redis的连接池和初始化redis模版操作类,自行替换其中的相关变量。
14、 <!-- redis -->
15、 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
16、 </bean>
17、 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
18、 <property name="hostName" value="${redis.host}" />
19、 <property name="port" value="${redis.port}" />
20、 <property name="password" value="${redis.pass}" />
21、 <property name="timeout" value="${redis.timeout}" />
22、 <property name="poolConfig" ref="jedisPoolConfig" />
23、 <property name="usePool" value="true" />
24、 </bean>
25、 <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
26、 <property name="connectionFactory" ref="jedisConnectionFactory" />
27、 </bean>
28、
29、 <!-- 将session放入redis -->
30、 <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
31、 <property name="maxInactiveIntervalInSeconds" value="1800" />
32、 </bean>
33、 这里前面几个bean都是操作redis时候使用的,最后一个bean才是spring-session需要用到的,其中的id可以不写或者保持不变,这也是一个约定优先配置的体现。这个bean中又会自动产生多个bean,用于相关操作,极大的简化了我们的配置项。其中有个比较重要的是springSessionRepositoryFilter,它将在下面的代理filter中被调用到。maxInactiveIntervalInSeconds表示超时时间,默认是1800秒。写上述配置的时候我个人习惯采用xml来定义,官方文档中有采用注解来声明一个配置类。
34、 然后是在web.xml中添加一个session代理filter,通过这个filter来包装Servlet的getSession()。需要注意的是这个filter需要放在所有filter链最前面。
35、 <!-- delegatingFilterProxy -->
36、 <filter>
37、 <filter-name>springSessionRepositoryFilter</filter-name>
38、 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
39、 </filter>
40、 <filter-mapping>
41、 <filter-name>springSessionRepositoryFilter</filter-name>
42、 <url-pattern>/*</url-pattern>
43、 </filter-mapping>
44、 这样便配置完毕了,需要注意的是,spring-session要求Redis Server版本不低于2.8。
45、 验证:使用redis-cli就可以查看到session key了,且浏览器Cookie中的jsessionid已经替换为session。
46、
47、 127.0.0.1:6379> KEYS *
48、 1) "spring:session:expirations:1440922740000"
49、 2) "spring:session:sessions:35b48cb4-62f8-440c-afac-9c7e3cfe98d3"

第七种:如果项目中用到shiro了,shiro是不带将session持久化到redis实现集群共享的,所以说需要自己实现或者找别人写好的,下面来说说自己实现,不管别人写还是自己实现思路都是一样的,了解了岂不是更好。(这个自己项目确实遇到这个问题了,通过网上的资料已经解决,参考的太多就不贴地址了,只说自己怎么弄的)



1、 配置shiro的xml
2、 <!-- SessionManager -->
3、 <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
4、 <!-- session存储的实现(此处为自己重写的sessionDao) -->
5、 <property name="sessionDAO" ref="redisSessionDAO" />
6、 <!-- 定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话 -->
7、 <property name="sessionValidationInterval" value="1800000"/>
8、 <property name="sessionValidationSchedulerEnabled" value="true"/>
9、
10、 <property name="sessionIdCookie" ref="sessionIdCookie"/>
11、 <property name="sessionIdCookieEnabled" value="true"/>
12、 </bean>

RedisSessionDao



1、 public class RedisSessionDao extends AbstractSessionDAO {
2、
3、 private static Logger logger = LoggerFactory.getLogger(RedisSessionDao.class);
4、
5、 /*
6、 * The Redis key prefix for the sessions
7、 */
8、 private static final String REDIS_SHIRO_SESSION = "shiro_redis_session:";
9、
10、 private static final Integer SESSION_VAL_TIME_SPAN = 18000;
11、
12、 /**
13、 * redis接口
14、 */
15、 @Resource(name = "cacheServiceImpl")
16、 private ICacheService iCacheService;
17、
18、 /**
19、 * @discription 创建session,保存到数据库
20、 *
21、 * @param session
22、 * @return
23、 *
24、 * @author zhaoqiang
25、 * @created 2017年3月3日 下午1:28:09
26、 */
27、 @Override
28、 protected Serializable doCreate(Session session) {
29、 Serializable sessionId = this.generateSessionId(session);
30、 this.assignSessionId(session, sessionId);
31、 saveSession(session);
32、 return sessionId;
33、 }
34、
35、 /**
36、 * @discription 获取session
37、 *
38、 * @param sessionId
39、 * @return
40、 *
41、 * @author zhaoqiang
42、 * @created 2017年3月3日 下午1:28:43
43、 */
44、 @Override
45、 protected Session doReadSession(Serializable sessionId) {
46、
47、 if (sessionId == null) {
48、 throw new NullPointerException("session id is empty");
49、 }
50、
51、 SimpleSession session = null;
52、
53、 try {
54、 byte[] value = iCacheService.getByte(buildRedisSessionKey(sessionId));
55、 session = SerializeUtil.unserialize(value, SimpleSession.class);
56、 } catch (Exception e) {
57、 e.printStackTrace();
58、 logger.error("get session error");
59、 }
60、 return session;
61、 }
62、
63、 /**
64、 * @discription 更新session的最后一次访问时间
65、 *
66、 * @param session
67、 *
68、 * @author zhaoqiang
69、 * @created 2017年3月3日 下午1:34:24
70、 */
71、 @Override
72、 public void update(Session session) {
73、 saveSession(session);
74、 }
75、
76、 /**
77、 * @discription 删除session
78、 *
79、 * @param session
80、 *
81、 * @author zhaoqiang
82、 * @created 2017年3月3日 下午1:35:48
83、 */
84、 @Override
85、 public void delete(Session session) {
86、 if (session == null) {
87、 logger.error("session can not be null,delete failed");
88、 return;
89、 }
90、
91、 Serializable id = session.getId();
92、 if (id == null) {
93、 throw new NullPointerException("session id is empty");
94、 }
95、
96、 try {
97、 iCacheService.delByString(buildRedisSessionKey(id));
98、 } catch (Exception e) {
99、 e.printStackTrace();
100、 logger.error("delete session error");
101、 }
102、 }
103、
104、 /**
105、 * @discription 获得活跃的session集合
106、 *
107、 * @return
108、 *
109、 * @author zhaoqiang
110、 * @created 2017年3月3日 下午2:05:22
111、 */
112、 @Override
113、 public Collection<Session> getActiveSessions() {
114、 Set<Session> sessions = new HashSet<Session>();
115、 try {
116、 Set<String> keys = iCacheService.keys(REDIS_SHIRO_SESSION);
117、
118、 if (keys == null || keys.size() == 0) {
119、 return sessions;
120、 }
121、
122、 for (String key : keys) {
123、 Session s = null;
124、 try {
125、 s = iCacheService.getObject(key, SimpleSession.class);
126、 } catch (ClassNotFoundException e) {
127、 e.printStackTrace();
128、 } catch (IOException e) {
129、 e.printStackTrace();
130、 }
131、 sessions.add(s);
132、 }
133、
134、 } catch (Exception e) {
135、 logger.error("[获得活跃的session集合(getActiveSessions)-error][" + e.getMessage() + "]");
136、 e.printStackTrace();
137、 }
138、 return sessions;
139、 }
140、
141、 /**
142、 * @discription 处理缓存中id名称
143、 *
144、 * @param sessionId
145、 * @return
146、 *
147、 * @author zhaoqiang
148、 * @created 2017年3月9日 下午1:13:45
149、 */
150、 private String buildRedisSessionKey(Serializable sessionId) {
151、 return REDIS_SHIRO_SESSION + sessionId;
152、 }
153、
154、 /**
155、 * @discription 持久化session到redis
156、 *
157、 * @param session
158、 *
159、 * @author zhaoqiang
160、 * @created 2017年3月9日 下午1:06:53
161、 */
162、 private void saveSession(Session session) {
163、 if (session == null || session.getId() == null) {
164、 throw new NullPointerException("session is empty");
165、 }
166、 try {
167、 String key = buildRedisSessionKey(session.getId());
168、 long sessionTimeOut = session.getTimeout() / 1000;
169、 Long expireTime = sessionTimeOut + SESSION_VAL_TIME_SPAN + (5 * 60);
170、
171、 iCacheService.setObject(key, session, new Integer(expireTime.toString()));
172、
173、 } catch (Exception e) {
174、 e.printStackTrace();
175、 logger.error("save session error");
176、 }
177、 }
178、 }

public class HttpSessionWrapper implements HttpSession {
  protected final Logger logger = LoggerFactory.getLogger(getClass());
   private String sid = "";
   private HttpServletRequest request;
   private HttpServletResponse response;
   private final long creationTime = System.currentTimeMillis();
   private final long lastAccessedTime = System.currentTimeMillis();
   private SessionMeta meta;
   public HttpSessionWrapper() {
   }
  public HttpSessionWrapper(String sid,SessionMeta meta, HttpServletRequest request,
       HttpServletResponse response) {
     this.sid=sid;
     this.request=request;
     this.response=response;
     this.meta=meta;
   }
   public Object getAttribute(String name) {
     logger.info(getClass()+"getAttribute(),name:"+name);
      Jedis jedis =null;
      Object obj =null;
      String jsonStr = null;
     try {
       jedis =JedisPoolStore.getInstance().getJedis(meta.getHost(), meta.getPort());
       jsonStr = jedis.get(name);
       if(jsonStr!=null||StringUtils.isNotEmpty(jsonStr)){
         jedis.expire(name, meta.getSeconds());// 重置过期时间
         obj =JSON.parseObject(jsonStr, User.class); //反序列对象
       }
       if (jedis != null) {
         JedisPoolStore.getInstance().returnJedis(jedis);
       }
       return obj;
     } 
     catch (JSONException je) {
       logger.error(je.getMessage());
         if (null != jedis)
           JedisPoolStore.getInstance().returnJedis(jedis);
       return jsonStr;
     }
     catch (Exception e) {
       logger.error(e.getMessage());
       if (e instanceof JedisException) {
         if (null != jedis)
           JedisPoolStore.getInstance().returnBrokenJedis(jedis);
       } else {
         if (null != jedis)
           JedisPoolStore.getInstance().returnJedis(jedis);
       }
       throw new HttpSessionException(" session 异常  getAttribute() name:"+name);
     }
  }
  public void setAttribute(String name, Object value) {
     logger.info(getClass()+"setAttribute(),name:"+name);
     Jedis jedis =null;
     try {
       jedis =JedisPoolStore.getInstance().getJedis(meta.getHost(), meta.getPort());
       if(value instanceof String){
         String value_ =(String) value;
         jedis.set(name,value_);//普通字符串对象
       }else{
         jedis.set(name, JSON.toJSONString(value));//序列化对象
       }

       jedis.expire(name, meta.getSeconds());// 重置过期时间
       if (jedis != null) {
         JedisPoolStore.getInstance().returnJedis(jedis);
       }
     } catch (Exception e) {
       logger.error(e.getMessage());
       if (e instanceof JedisException) {
         if (null != jedis)
           JedisPoolStore.getInstance().returnBrokenJedis(jedis);
       } else {
         if (null != jedis)
           JedisPoolStore.getInstance().returnJedis(jedis);
       }
       throw new HttpSessionException(" session 异常  setAttribute() name:"+name+",value:"+value);
     }

  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public void invalidate() {
     logger.info(getClass()+"invalidate()");
  }

  public void removeAttribute(String name) {
     logger.info(getClass()+"removeAttribute(),name:"+name);
     if(StringUtils.isNotEmpty(name)){
       Jedis jedis =null;
       try {
         jedis =JedisPoolStore.getInstance().getJedis(meta.getHost(), meta.getPort());
         jedis.del(name);
         if (jedis != null) {
           JedisPoolStore.getInstance().returnJedis(jedis);
         }
       } catch (Exception e) {
         logger.error(e.getMessage());
         if (e instanceof JedisException) {
           if (null != jedis)
             JedisPoolStore.getInstance().returnBrokenJedis(jedis);
         } else {
           if (null != jedis)
             JedisPoolStore.getInstance().returnJedis(jedis);
         }
         throw new HttpSessionException(" session 异常  removeAttribute() name:"+name);
       }
     }

  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public Object getValue(String name) {
    return null;
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public Enumeration getAttributeNames() {
     return  null;

  }       
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public String[] getValueNames() {
     return  null;   
   }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public void putValue(String name, Object value) {
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public void removeValue(String name) {
  }

  public long getCreationTime() {
     return  creationTime;
  }

  public String getId() {
     logger.info(getClass()+"getId():"+sid);
    return sid;
  }

  public long getLastAccessedTime() {
    return lastAccessedTime;
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public ServletContext getServletContext() {
    return null;
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public void setMaxInactiveInterval(int interval) {
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public int getMaxInactiveInterval() {
    return 0;
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public HttpSessionContext getSessionContext() {
    return null;
  }
  /**
   \* 不可用
   \* @deprecated
   \* 
   */
  public boolean isNew() {
     logger.info(getClass()+"isNew()");
    return false;
  }
}

文章永久链接:https://tech.souyunku.com/29726

未经允许不得转载:搜云库技术团队 » 集群session共享方案

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们