We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RedisSessionDao完全依赖于redis,如果redis挂掉了,或者本来redis就没有启动,那么该组件会导致项目全部不可用。所以考虑一下可用性。
private static Logger logger = LoggerFactory.getLogger(SessionCache.class); private String keyPrefix = "shiro_redis_session:"; private final CacheClusterClient cacheClusterClient; private final int timeOut ; public SessionCache(CacheClusterClient cacheClusterClient, int timeOut) { this.cacheClusterClient = cacheClusterClient; this.timeOut = timeOut; } /** * 读取session * * @param sessionId * @return */ public Session readSession(Serializable sessionId) { try { return sessionCache.get(sessionId); } catch (Exception e) { return null; } } /** * 保存session * * @param session */ public void saveSession(Session session) { if(session == null || session.getId() == null){ logger.error("session or session id is null"); return; } byte[] key = getKey(session.getId()); byte[] value = SerializeUtil.serialize(session); session.setTimeout(timeOut * 1000); try{ cacheClusterClient.set(key, value); cacheClusterClient.expire(key,timeOut); } catch (Exception e) { logger.error("###########Redis Connect Failed###########", e); //save to local sessionCache.put(session.getId(),session); } } /** * 作废session * * @param sessionId */ public void invalid(Serializable sessionId) { sessionCache.invalidate(sessionId); try{ cacheClusterClient.del(getKey(sessionId)); } catch (Exception e) { logger.error("###########Redis Connect Failed###########", e); } } /** * 所有活动的session * * @return */ public Collection<Session> getActive() { return sessionCache.asMap().values(); } /////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ private LoadingCache<Serializable,Session> sessionCache = CacheBuilder.newBuilder() .maximumSize(100)//设置缓存最大容量为100 .expireAfterWrite(10, TimeUnit.MINUTES)//设置写缓存后30分钟过期,过期后会触发removalListener .concurrencyLevel(4)//并发级别为4,并发级别是指可以同时写缓存的线程数 .removalListener(new RemovalListener<Object, Object>() {//这段代码可以移除 @Override public void onRemoval(RemovalNotification<Object, Object> notification) { logger.debug("session was removed with key" + notification.getKey() + " cause is :" + notification.getCause()); } }) .build(new CacheLoader<Serializable,Session>() {//如果缓存中根据Key没有取到值,那么执行这里面的操作了 @Override public Session load(Serializable key) throws Exception { return readRedis(key);//当返回null的时候会抛异常,CacheLoader.InvalidCacheLoadException } }); private byte[] getKey(Serializable sessionId){ String preKey = this.keyPrefix + sessionId; return SerializeUtil.serialize(preKey); } private Session readRedis(Serializable sessionId) { if(sessionId == null){ logger.error("session id is null"); return null; } try { byte[] key = getKey(sessionId); byte[] value = cacheClusterClient.get(key); if(value == null) return null; Session s = (Session) SerializeUtil.deserialize(value); return s; } catch (Exception e) { logger.error("Redis Connect Failed! Read Err!",e); } return null; }
这个可以 redis的一些cluster的方案,这里不做衍生。
The text was updated successfully, but these errors were encountered:
建议使用Redis sentinel或者Redis cluster来解决可用性问题,保持Shiro-redis的简单,简单的代码比较robust. 也容易阅读
Sorry, something went wrong.
No branches or pull requests
RedisSessionDao完全依赖于redis,如果redis挂掉了,或者本来redis就没有启动,那么该组件会导致项目全部不可用。所以考虑一下可用性。
1、确保单机一定可用:
2、提升redis组件本身的可用性:
这个可以 redis的一些cluster的方案,这里不做衍生。
The text was updated successfully, but these errors were encountered: