集群环境中的故障​​转移不适用于 JSF 2、Richfaces 4、Tomcat 7

Posted

技术标签:

【中文标题】集群环境中的故障​​转移不适用于 JSF 2、Richfaces 4、Tomcat 7【英文标题】:Failover in clustered environment does not work with JSF 2, Richfaces 4, Tomcat 7 【发布时间】:2013-09-24 21:41:05 【问题描述】:

我有一个集群环境,Apache 2.2.6 和 mod_proxy 通过 AJP13 指向 Tomcat 7.0.26,带有粘性会话。

httpd.conf的配置是这样的:

    <Proxy balancer://mycluster2>
         BalancerMember ajp://192.168.0.1:8009 route=tomcat1
         BalancerMember ajp://192.168.0.2:8009 route=tomcat2
         ProxySet lbmethod=byrequests
    </Proxy>
    ProxyPass /MyApp balancer://myCluster2/MyApp stickysession=JSESSIONID
    ProxyPassReverse /MyApp https://apache_server/MyApp

在我的 tomcat server.xml 文件中,我已经在&lt;Host&gt; 标签内正确配置了集群(只发布了 tomcat1 文件,tomcat2 相同,只更改了 ip):

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>


<Connector executor="tomcatThreadPool"
           port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

   <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

...

   <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
            channelSendOptions="8">
            <Manager className="org.apache.catalina.ha.session.DeltaManager"
                    expireSessionsOnShutdown="false"  notifyListenersOnReplication="true" />
            <Channel className="org.apache.catalina.tribes.group.GroupChannel">
                    <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000" />
                    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.0.1" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" />
                    <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
                            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
                    </Sender>
                    <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" />
                    <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" />
                    <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor" />
            </Channel>
            <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter="" />
            <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" />
            <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" />
            <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />
    </Cluster>

此配置对任何 jsp webapp 都具有吸引力,它复制会话并在经典故障转移步骤测试用例的故障转移中完美运行:

1.- Tomcat1 starts.
2.- Tomcat2 starts.
3.- A request is processed by the balancer: https://apache_server/MyApp and sent to Tomcat1.
4.- Some operations are performed (i. e. refresh page with a counter as session attribute).
5.- Tomcat1 is killed.
6.- User refresh page and the session counter follows counting in Tomcat2.

所以,在这一点上,我很清楚 apache 和 Tomcat 都没有错误配置。然后我使用 MyApp。首先,它在web.xml中有&lt;distributable/&gt;标签。

接下来,我成功地将它部署在 Tomcat1 和 Tomcat2 上,我看到 Tomcat 正在为我的应用程序在节点之间进行多播和共享信息:

INFO: Gestor [/MyApp], requiriendo estado de sesión desde org.apache.catalina.tribes.membership.MemberImpl[tcp://192, 168, 0, 1:4000,192, 168, 0, 1,4000, alive=5113068, securePort=-1, UDP Port=-1, id=-31 113 14 29 99 -58 77 -75 -111 66 -103 86 102 -108 120 61 , payload=, command=, domain=, ]. Esta operación se agotará si no se recibe estado de sesión dentro de 60 segundos.
19-sep-2013 18:49:51 org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor report
INFO: ThroughputInterceptor Report[
        Tx Msg:1 messages
        Sent:0,00 MB (total)
        Sent:0,00 MB (application)
        Time:0,00 seconds
        Tx Speed:0,12 MB/sec (total)
        TxSpeed:0,12 MB/sec (application)
        Error Msg:0
        Rx Msg:1 messages
        Rx Speed:0,00 MB/sec (since 1st msg)
        Received:0,00 MB]

19-sep-2013 18:49:51 org.apache.catalina.ha.session.DeltaManager waitForSendAllSessions
INFO: Gestor [/MyApp]; estado de sesión enviado a las 19/09/13 18:49 recibido en 106 ms.

我尝试重现前面提到的导航,我可以在 Tomcat 管理器中看到我的域对象被复制的两个节点(它们都实现了Serializable)。

由于某种原因,我的 JSF com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap 没有复制所有对象。事实上,Backup 节点在该会话属性中总是比 Primary 节点少一个对象。

在第 6 点,杀死 Tomcat1 并刷新页面后,会话没有恢复,用户被发送到注销屏幕,使会话无效。

MyApp 以前在非集群环境中工作。这是MyApp web.xmlSTATE-SAVING的配置:

    <context-param>
     <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
     <param-value>server</param-value>
    </context-param>

即使我尝试从 JSF 2.1.4 升级到 2.1.21,我也得到了同样的错误。如果不更改 MyApp 中的很多东西,我就无法升级到 2.2.3(这是在生产中,这是一个长期开发项目,所以在考虑对整个项目进行重构之前,我必须全部尝试)。

我也尝试将它放在我的 web.xml 中,结果更糟,因为它在 LogicalViewMap 中复制的对象更少:

    <context-param>
        <param-name>com.sun.faces.serializeServerState</param-name>
        <param-value>true</param-value>
    </context-param>

我的 faces-config.xml 没有什么特别的。

我也尝试将 JSF 升级到 2.2.3,但在这种情况下,项目根本无法运行,因为我使用的是 Richfaces 4.0.0-final,我需要重构更多代码。

此时我在想 JSF 2 与 Tomcat 集群不兼容。有人用 Tomcat Clustering 和 JSF 2 配置项目吗?

任何帮助将不胜感激。

【问题讨论】:

您在 Catalina 日志文件中看到任何错误吗? 不,没有错误。事实上,当我启动 Tomcat 时,我看到了 MyApp 的这个条目,而没有更多关于会话的条目 19-sep-2013 18:49:51 org.apache.catalina.ha.session.DeltaManager waitForSendAllSessions INFO: Gestor [/MyApp]; session state sent at 19/09/13 18:49 received in 106 ms. 【参考方案1】:

我有类似的问题,但在 weblogic 环境中。请看jsf session failover

希望这可能会有所帮助。

【讨论】:

我在发布这个新帖子之前看到了那个帖子。我尝试了那里公开的配置,但对于这种情况没有解决方案。还是谢谢。

以上是关于集群环境中的故障​​转移不适用于 JSF 2、Richfaces 4、Tomcat 7的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 快速连接故障转移不适用于 ODP.NET。获取连接请求超时错误

2012故障转移群集的搭建(本人小白)

第十课——cluster故障转移操作,codis部署

2 节点 Cassandra 集群中的故障转移和复制

PrimeFaces 4.0/JSF 2.2.x 中的文件上传不适用于 AJAX - javax.servlet.ServletException:请求内容类型不是多部分/表单数据

Spring Security 3.1.4 taglib 授权/身份验证不适用于 Tomcat 7 上 JSF 2.2 中的角色层次结构