集羣session共享方案

轉博友的比較有用

參考文章:使用Spring Session做分佈式會話管理分佈式應用session會話管理-基於redis

說在前面:由於這篇文章參考了別人的,自己也總結了,所以很不要臉的把這篇文章標爲了原創(捂臉)。但是參考的文章都寫在最上面了。

在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微笑臉,省的自己造輪子了,知道原理就行)。

     前三種方案:出於安全、成本(自己搞着玩不好弄)、無法完全做到7*24*365不宕機,個人不推薦。有興趣的自己研究吧。

     剩下的四種方案大體思路其實都一樣,存到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接口

[java] view plain copy
  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
[java] view plain copy
  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
[java] view plain copy
  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
[html] view plain copy
  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>  
第六種:(沒用過,感覺這個人的挺靠譜,直接粘貼過來了,參考博客的地址也在最上面)

[html] view plain copy
  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實現集羣共享的,所以說需要自己實現或者找別人寫好的,下面來說說自己實現,不管別人寫還是自己實現思路都是一樣的,瞭解了豈不是更好。(這個自己項目確實遇到這個問題了,通過網上的資料已經解決,參考的太多就不貼地址了,只說自己怎麼弄的)

[html] view plain copy
  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

[java] view plain copy
  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. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章