为每个请求生成的新会话ID

时间:2017-06-14 20:32:42

标签: java google-kubernetes-engine

问题摘要:

为我的应用程序中的每个请求生成新会话ID,但仅在Google Cloud Container Engine基础结构中生成。

根本原因:

我找到了问题的根本原因。为Ingress设置的会话亲缘关系不能像我预期的那样工作。以下是它的创建方式:

  1. 我正在使用2个副本(带有servlet的基本java应用程序)创建部署
  2. 我正在创建NodePort服务,如here所述(但使用YAML)
  3. 我正在使用YAML
  4. 创建Ingress控制器
  5. 我正在通过Google Cloud Console向Ingress添加基于cookie的会话亲和力
  6. 以下是我在浏览器中刷新页面时得到的内容(POD名称添加在“[]”中):

    [app-deployment-428779295-3xq7f] Session created: node01peqkxiewv08i1hkh0zonc8fmw0
    [app-deployment-428779295-lp1r2] Session created: node017hf0svs0n6u816virgk4qkxk40
    [app-deployment-428779295-3xq7f] Session created: node030t1v2oamg3p1x3tw55m2tdno1
    [app-deployment-428779295-3xq7f] Session exists: node030t1v2oamg3p1x3tw55m2tdno1
    [app-deployment-428779295-lp1r2] Session created: node0drzofij3ljx1tgn2z3dcj12y1
    [app-deployment-428779295-lp1r2] Session exists: node0drzofij3ljx1tgn2z3dcj12y1
    [app-deployment-428779295-lp1r2] Session exists: node0drzofij3ljx1tgn2z3dcj12y1
    [app-deployment-428779295-3xq7f] Session created: node01wlgfm248y7f3fagzuu3thga82
    [app-deployment-428779295-lp1r2] Session created: node0qiqpch5b1u4g1lvbphkj3djqh2
    [app-deployment-428779295-lp1r2] Session exists: node0qiqpch5b1u4g1lvbphkj3djqh2
    [app-deployment-428779295-lp1r2] Session exists: node0qiqpch5b1u4g1lvbphkj3djqh2
    [app-deployment-428779295-3xq7f] Session created: node01gfdfatrj0premffkwywc5ori3
    

    问题是 - 如何解决?

    原始问题说明:

    • Spring MVC应用程序(也在简单的servlet上测试,结果相同,所以情况并非如此)
    • 在jetty 9.4.6 docker镜像上运行(默认配置;也发生在tomcat 8.5.15 docker镜像上)
    • 部署为ROOT.war的应用程序
    • 应用程序部署在2个节点(2个POD)上,具有Ingress加载缓存,HTTPS和基于cookie的会话关联。
    • 设置explicite cookie域和路径没有帮助。
    • 应用程序管理的其他Cookie工作正常

    当我从jetty-maven-plugin或本地的docker镜像运行时,问题不会发生。

    还有其他人遇到过这样的问题吗?

1 个答案:

答案 0 :(得分:0)

我目前通过只保留1个副本并设置sessionAffinity: None(这是默认设置)修复了我的问题,但这对可伸缩应用程序没有帮助。

我想到的第一个解决方案是创建Redis pod并在我的spring应用程序中将其配置为会话持有者,然后我离开sessionAffinity: None,因为我没有在我的pod内存中保存安全上下文,相反,我将它留在我的Redis数据库中,因此,哪个Spring应用程序pod将处理请求并不重要,因为它可以通过询问Redis数据库来识别会话。通过这样做,您不会受到部署基础架构的限制。您可以查看this指南。

第二种解决方案是通过将OAuth2实现与授权服务器配合使用来配置无会话应用程序,并将spring应用程序配置为客户端,但这已经是一个更复杂的解决方案,需要更多工作。