我们有网站在Tomcat上运行。其中一些是群集的(通常是群集中的两个节点),并且一切正常。
但是,我们有一对会话未正确复制,即使配置似乎与我们的其他(工作)安装相似。
当我通过JMX检查Tomcat节点时,我看到Cluster.modelerType设置为org.apache.catalina.ha.tcp.SimpleTcpCluster,用于工作和非工作站点。
但是,当我查看管理器时,我看到为工作节点加载了增量管理器,但为不工作的节点加载了标准管理器。
网络.xml确实设置了"<可分发 />"。此外,"<经理 />"在上下文中被注释.xml。所以,这两个不是问题。
这是来自服务器的代码片段.xml(Tomcat 7.0.42)
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.3.4"
port="23810"
frequency="500"
dropTime="3000"
/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.1.144"
/>
</Channel>
</Cluster>
任何想法配置的哪一部分可能导致SimpleTcpCluster处于活动状态,但StandardManager正在使用中?
这是 StandardContext 中的代码(取自 Tomcat 8,但对于许多版本并没有真正改变),用于创建管理器
// Acquire clustered manager
Manager contextManager = null;
Manager manager = getManager();
if (manager == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("standardContext.cluster.noManager",
Boolean.valueOf((getCluster() != null)),
Boolean.valueOf(distributable)));
}
if ( (getCluster() != null) && distributable) {
try {
contextManager = getCluster().createManager(getName());
} catch (Exception ex) {
log.error("standardContext.clusterFail", ex);
ok = false;
}
} else {
contextManager = new StandardManager();
}
}
看起来您检查了正确的内容。此时,我将 IDE 连接到 Tomcat 实例,并使用远程调试来逐步完成这部分代码,以找出使用错误管理器的原因。
事实证明,修复它的方法是在我们的 web.xml 文件中添加元数据-complete="true"。
这似乎是我们 servlet 规范设置为 3.0 的站点所必需的(不是 2.5 的要求)
如果没有这个,正在加载的东西(我猜来自我们使用的一些第三方 jar)可能会撤消"可分发"。 事实证明,我们使用的第三方库之一包含一个网络标签片段,但并没有说它是"可分发的",那么整个应用程序就不是。
Servlet 规范 3.0,第 8.2.3 节,5.g.ix 说:网络.xml结果 从合并被认为是<可分发的>只有当它的所有网络 片段也被标记。 Servlet 规范 3.1可分发的>