JBoss Clustering 和 Lighttpd 负载平衡显示不一致的行为
•浏览 1
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 配置如下:
server.modules += ("mod_proxy" ) proxy.balance ="fair" proxy.server = ("" => (("host" =>"Machine03","port" => 1100 ), ("host" =>"Machine04","port" => 1100 )) 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 // 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; }
jndi.properties 有以下条目
server.modules += ("mod_proxy" ) proxy.balance ="fair" proxy.server = ("" => (("host" =>"Machine03","port" => 1100 ), ("host" =>"Machine04","port" => 1100 )) 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 // 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; }
其他信息
无法弄清楚为什么,在我关闭机器并从应用程序中注销后,Tomcat 不再具有对 JBoss 机器的代理引用。
我现在已经解决了。感谢 smallworld 为我指明了正确的方向。
发生的事情是我们正在缓存从 jndi 查找中获得的远程接口。现在据我了解,此远程接口仅指向集群中的一个特定服务器。 (我们认为远程接口足够智能以识别服务器已关闭。看起来智能在您进行查找时与初始上下文有关)。因此,一旦服务器关闭,对该远程接口进行的任何 ejb 调用都会连接到被关闭的服务器。因此,为了解决这个问题,我们停止缓存远程接口,并在每次需要该 EJB 的服务时进行查找。如果任何服务器关闭,查找将返回启动并运行的服务器的远程接口。有了这个,集群可以完美运行!所以,伙计们,你的代码应该是这样的:
server.modules += ("mod_proxy" )
proxy.balance ="fair"
proxy.server = ("" => (("host" =>"Machine03","port" => 1100 ),
("host" =>"Machine04","port" => 1100 ))
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
// 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;
}
注释行是导致问题的行。现在唯一留给我研究的是如果有更好的解决方案。