博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

昨天在集成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异常需谨慎呀-- 不然发生一次次的惨案。