关于 java:JBoss Clustering 和 Lighttpd 负载平衡显示不一致的行为 | 珊瑚贝

JBoss Clustering and Lighttpd Load Balancing displaying inconsistent behaviour


问题

我们在不同的机器上安装了两个 JBossAS 4.2.3,它们是集群的。我们还使用 Lighttpd 作为负载平衡器,并放置在我们的 Tomcat 服务器(Tomcat 服务器没有集群)和 JBoss 服务器之间。一旦所有服务器都启动并运行,应用程序就会完美运行。如果我关闭了一台 JBoss 服务器,请求将按预期重定向到另一台服务器。注销应用程序后,我的问题就开始了。在尝试重新登录应用程序时,我收到一个异常,提示 Tomcat 无法连接到已关闭的服务器。

服务器设置

  • Machine01 – Tomcat7
  • Machine02 – Tomcat7
  • Machine03 – JBoss 4.2.3
  • Machine04 – JBoss 4.2.3
  • Machine05 – Lighttpd 1.4.28
  • 其他信息

    • 所有机器都使用 Ubuntu 12.04 操作系统。
    • JBoss 机器是集群的。
    • EAR 被放置在 all/deploy 文件夹中。
    • JBossAS 使用以下命令启动 – ./run.sh -b 0.0.0.0 -c all –partition=SomePartitionName &> /dev/null &。
    • Tomcat7 作为服务运行,因此它们作为 sudo service tomcat7 start 启动。
    • Lighttpd 被配置为 JBoss 机器的负载平衡器。
    • lighttpd 上的 mod_proxy 配置如下:

      1
      2
      3
      4
      server.modules += (“mod_proxy” )
      proxy.balance =“fair”
      proxy.server = (“” => ((“host” =>“Machine03”,“port” => 1100 ),
                             (“host” =>“Machine04”,“port” => 1100 ))
    • jndi.properties 有以下条目

      1
      2
      3
      java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
      java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
      java.naming.provider.url=Machine05:80

    无法弄清楚为什么,在我关闭机器并从应用程序中注销后,Tomcat 不再具有对 JBoss 机器的代理引用。

    • 你是如何管理会话的?粘不粘?
    • 再次澄清一下,Lighttpd 用作 JBoss 机器而不是 Tomcat 机器的负载平衡器。因此,在当前设置中,两个 Tomcat 管理它们自己的会话,它们既不是集群的,也不是它们的会话同步的。 Tomcat 充当独立服务器,与单个 JBoss 集群通信。
    • @Rishabh我不确定这是否有帮助….除非您的应用程序是无状态的,否则我会要求您查看部署架构-根据您上面的描述,如果Tomcat实例出现故障,那么您丢失了用户会话信息,因此用户没有已知的状态。我相信您对此有充分的理由……但作为架构师,在”有状态应用程序”中,即使其中一个状态机出现故障,我的重点也会放在维护用户状态上。
    • 现在看看你描述的问题……很明显,lighttpd 无法识别新会话的底层 JBoss 集群的状态。您是否尝试过从不同的浏览器客户端创建多个新会话以查看您的体验是否有所不同?我的意思是…尝试从不同的客户端创建一堆新会话,看看你是否收到”无法连接”错误。希望这会引导您找到解决方案。
    • 嗨 smallworld,我们的耳朵由无状态会话 bean 组成,所以我不担心 jboss 的会话。就 tomcat 而言,我们将在处理它们的集群时实现会话复制。即使我只使用一个 tomcat 进行连接,我也会面临上述问题。 Tomcat集群,会话复制是下一步。现在我坚持让 jboss 正常工作。简单来说,Tomcat为什么还要去尝试连接已经挂掉的JBoss呢?这意味着 JBoss 中的 HA 功能不起作用。我现在已经重新检查了数百次配置。
    • @Rishabh HA 是一个复杂的架构,根据您笔记中概述的详细信息,我很难准确指出哪里可能出错。集群 HA JBoss 应该通过多播消息来宣传其可用性,并且代理/负载平衡器应该根据其知道谁可以处理请求来管理工作负载的分配。我只能告诉您,您的 lighttpd 代理无法在您的场景中检测到故障的 JBoss。请参阅 docs.jboss.org/jbossclustering/cluster_guide/5.1/pdf/…的第 21/22 页
    • 最后一点:如果我理解正确,您正在将会话 bean 从您的 JBoss 访问到您的 Tomcat(在您的 JSP 层内)以呈现对用户请求的响应。您很可能在这里处理 JNDI 查找缓存 – 即在您的 Tomcat 层中”缓存对无状态会话 bean 的一些陈旧引用”,并尝试访问它们。为了验证这个假设,您可以尝试从混合中删除 lighttpd 代理。您可能想通过谷歌搜索”jndi 查找缓存”来了解一下
    • @smallworld:我摆脱了 lighttpd 并尝试直接访问集群。问题仍然存在。 \\’jndi 查找缓存\\’ 是有意义的。将解决此问题并更新您。
    • @Rishabh 很高兴看到假设得到验证。在这一点上,我几乎可以向您保证,您正在处理 jndi 查找缓存和过时引用问题。祝你好运解决那部分!
    • 谢谢@smallworld。正如您所说,”jndi 查找缓存”是根本原因。


    我现在已经解决了。感谢 smallworld 为我指明了正确的方向。
    发生的事情是我们正在缓存从 jndi 查找中获得的远程接口。现在据我了解,此远程接口仅指向集群中的一个特定服务器。 (我们认为远程接口足够智能以识别服务器已关闭。看起来智能在您进行查找时与初始上下文有关)。因此,一旦服务器关闭,对该远程接口进行的任何 ejb 调用都会连接到被关闭的服务器。因此,为了解决这个问题,我们停止缓存远程接口,并在每次需要该 EJB 的服务时进行查找。如果任何服务器关闭,查找将返回启动并运行的服务器的远程接口。有了这个,集群可以完美运行!所以,伙计们,你的代码应该是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        // Some where at class level we have the following map declared
        private static final Map remoteEJBHashMap = new HashMap(100, 0.9f);

    public static final < T > T getEJBInterface(String jndiLookupName) {
        String jndiName = jndiLookupMap.get(jndiLookupName);
        T ejbInterface = null;
        //T ejbInterface = (T) remoteEJBHashMap.get(jndiLookupName);
        //if (ejbInterface == null) {
            try {
                ejbInterface = (T) ctx.lookup(jndiName);
            } catch (NamingException e) {
                throw new RuntimeException(e);
            }
            //remoteEJBHashMap.put(jndiLookupName, ejbInterface);
        //}
        return ejbInterface;
    }

    注释行是导致问题的行。现在唯一留给我研究的是如果有更好的解决方案。


    来源:https://www.codenong.com/16607113/

    微信公众号
    手机浏览(小程序)
    0
    分享到:
    没有账号? 忘记密码?