中信国际inMotion项目Session id重复问题总结

中信国际inMotion项目Session id重复问题总结

  1. Tomcat默认开启了Request​对象的复用,回收时先清理attribute​再清理header

  2. Spring session的会话管理机制分为3个步骤

    1. request​的attribute中获取session对象,获取到则使用。
    2. 从请求中(如请求头)获取sessionid,再从如redis等会话仓库中获取session,暂存到request的attribute中然后返回。
    3. 创建新的session,暂存到request的attribute中然后返回。
  3. 正常情况下,请求结束后tomcat会回收request​对象,不会出现问题。

  4. 本次原因在于request​对象在应用层的代码使用上出现了意外的泄露,主交易线程结束后,request​对象仍被使用,在一定的时间间隙时,会导致2.b的机制被重新触发,致使session对象被遗留在request​对象中,后续复用出现问题。

    1. 应用层在controller​层通过异步线程池的方式调用了另一个controller​的业务方法。
    2. 该异步线程池使用了decorator​机制将RequestContextHolder​上下文复制到了异步线程,导致异步线程能获取到主交易线程的request​。
    3. 主交易线程提交了异步任务后不等待异步任务完成就结束了当前交易,导致tomcat对request​对象进行了回收
    4. 应用层通过aop​方式对每个controller​进行了切面拦截,拦截代码中使用了类似:request.getSession()​方法获取会话。
    5. 如果在tomcat回收了attribute​后,还没有回收header​之前,触发了getSession​调用,就会出现session泄露问题。