随笔 - 22, 文章 - 0, 评论 - 97, 阅读 - 58658
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

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

 

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示