【问题标题】:Load Balancing Eclipse Scout application负载平衡 Eclipse Scout 应用程序
【发布时间】:2022-06-22 18:17:35
【问题描述】:

我尝试将 Eclipse Scout 应用程序放在代理后面,使用 HAProxy 和 Docker 以及两个 Tomcat 容器,但我遇到了一些问题。 如果只有一台服务器处于活动状态,或者两者都处于活动状态,则应用程序工作正常。但是当活动服务器关闭时,我被重定向到登录屏幕。此外,当只有一台服务器处于活动状态并启动第二台服务器时,我也会被重定向到登录并且会话丢失。

我想达到什么目标? 如果第一个 Tomcat 实例过载或活动 Tomcat 实例关闭,则将流量分配到另一个 Tomcat 实例。 部署新版本时,如果可能的话,我想:

  1. 关闭 Tomcat1,流量重定向到 Tomcat2
  2. 放置新的 .war 文件并部署它。
  3. 开启 Tomcat1
  4. 关闭 Tomcat2,流量重定向到新版本的 Tomcat1
  5. 放置新的 .war 并部署它
  6. 打开 Tomcat2。

这是我的 haproxy.cfg:

global
  stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners
  log stdout format raw local0 info

defaults
  mode http
  timeout client 10s
  timeout connect 5s
  timeout server 10s
  timeout http-request 10s
  log global

frontend stats
  bind *:8404
  stats enable
  stats uri /
  stats refresh 10s

frontend myfrontend
  bind :80
  default_backend webservers

backend webservers
  dynamic-cookie-key MYKEY
  cookie JSESSIONID prefix nocache
  option prefer-last-server
  stick-table type string len 36 size 1m expire 8h
  stick on cookie(JSESSIONID)
  server tomcat1 tomcat1:8080 cookie tomcat1 check
  server tomcat2 tomcat2:8080 cookie tomcat2 check

我试过了:

  • 没有 dinamic-cookie-key 的 HAProcy 配置
  • 将JVMRoute放到每个tomcat实例上,并命名为tomcat1tomcat2
  • 在每个 myapp.server.war config.properties 文件中添加 scout.nodeId 配置属性,将它们命名为 tomcat1tomcat2
  • 将每个 tomcat 实例中 server.xml 中的 sessionCookiePath 设置为“/”路径。

每次我得到相同的结果。会话无效,重定向到 /logout。

这是我在开发者工具中查看时的会话,当 tomcat2 处于活动状态时,会话具有 tomcat2 前缀和后缀: JSESSIONID tomcat1~10AD131758FD28D179111B2261ADD9BF.tomcat1

我正在使用:

  • 侦察兵 11
  • Tomcat 8.5.79
  • OpenJDK
  • HAProxy 2.4

在切换服务器时,我可以尝试更多什么来获得活动会话?我做错了什么?

谢谢!

【问题讨论】:

    标签: tomcat load-balancing tomcat8 haproxy eclipse-scout


    【解决方案1】:

    在经典 Scout 中,您在应用程序中看到的所有内容都由 UI 服务器上的客户端模型管理。这个有状态的客户端模型由IClientSession 组成。 (这就是为什么您可以重新加载页面而一切仍然存在的原因。)

    很遗憾,构成客户端模型的类(桌面、大纲、表单、字段等)不可序列化。这意味着它们不能“移动”到其他服务器实例。如果服务器宕机,它的所有状态都会丢失并且无法恢复。因此,在该服务器上具有客户端会话的所有用户都会自动注销。

    解决这个问题基本上有两种方法:

    1. 逐步淘汰服务器 A 上的用户,方法是更新您的负载平衡器,以便始终将新会话重定向到服务器 B,但现有会话保持不变。当服务器 A 上的最后一个会话消失时,您可以更新它,然后在负载均衡器上再次启用它。然后对服务器 B 做同样的事情。

      缺点:

      • 此过程非常缓慢,因为最后一个用户退出可能需要一段时间。您可能希望向他们发送通知,例如“此服务器将在 1 小时后关闭,请保存您的工作并重新登录”,以加快处理速度。
      • 有一段时间,服务器 B 必须处理整个工作负载。
    2. 重建您的应用程序并使用无状态架构。前端逻辑完全在浏览器中运行。对后端服务的调用是无状态的,例如不要依赖服务器端会话。这可以使用ScoutJS 或任何其他前端框架来实现。

      缺点:

      • 需要用 JavaScript 重新实现整个前端代码。
      • 范式改变。许多方便的功能必须被替换或重新设计(例如服务隧道、输入验证、授权)。

    【讨论】:

      猜你喜欢
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 2013-10-25
      • 1970-01-01
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多