zoukankan      html  css  js  c++  java
  • spring boot集成shiro-redis时,分布式根据seesionId获取session报错排查总结

    昨天在集成shiro-redis的时候,使用sessionId在其他微服务获取用户的session时,发生错误:There is no session with id [xxx]

    查遍了所有资料,基本上说的时cookieId造成的,和我的问题明显不一致,无奈只能down源码,调试跟踪。发现错误代码是因为RedisSessionDAO.doReadSession方法catch了异常后,没有抛出造成的,直接返回一个session 为null的返回值,上代码:

    @Override
        protected Session doReadSession(Serializable sessionId) {
            if (sessionId == null) {
                logger.warn("session id is null");
                return null;
            }
    
            if (this.sessionInMemoryEnabled) {
                Session session = getSessionFromThreadLocal(sessionId);
                if (session != null) {
                    return session;
                }
            }
    
            Session session = null;
            logger.debug("read session from redis");
            try {
                session = (Session) valueSerializer.deserialize(redisManager.get(keySerializer.serialize(getRedisSessionKey(sessionId))));
                if (this.sessionInMemoryEnabled) {
                    setSessionToThreadLocal(sessionId, session);
                }
            } catch (SerializationException e) {
                logger.error("read session error. settionId=" + sessionId);
            }
            return session;
        }

     这句代码:session = (Session) valueSerializer.deserialize(redisManager.get(keySerializer.serialize(getRedisSessionKey(sessionId))));是我的使用方法中出现There is no session with id的原因。因为我封装 的AuthUser,在另外的微服务中未引用,造成了反序列化异常。

    RedisSeesionDAO在此处catch后,并没有再继续抛出,从而使AbstractSessionDAO.readSeesion方法调用RedisSessionDAO重写的doReadSession后,得到了为nullsession,认为没有获取到session,然后抛出There is no session with id错误。

    readSeesion的代码:

      public Session readSession(Serializable sessionId) throws UnknownSessionException {
            Session s = doReadSession(sessionId);
            if (s == null) {
                throw new UnknownSessionException("There is no session with id [" + sessionId + "]");
            }
            return s;
        }

    所以,综合来说,我这次排查那么久,罪魁祸首是RedisSeesionDAO错误处理了异常,使上层调用方法不知道内部发生了什么错误,使上层方法抛出了一个与实际错误不相干的异常,让我绕了好大的圈子。

    公共组件catch异常需谨慎呀-- 不然发生一次次的惨案。

  • 相关阅读:
    二级缓存
    java面试题
    BRD,MRD,PRD文档
    程序做处理时,try..catch和if..else的区别
    关于java中字符串截取
    导出oracle数据库表(备份表)操作命令
    WSDL文件生成java类
    Linux下redis安装(单机版)
    Springboot2.0访问Redis集群
    Spring Cloud Sleuth通过Kafka将链路追踪日志输出到ELK
  • 原文地址:https://www.cnblogs.com/chongsha/p/11931109.html
Copyright © 2011-2022 走看看