JSF会话故障转移和部分状态保存 [英] JSF Session Fail over and Partial State Saving

查看:133
本文介绍了JSF会话故障转移和部分状态保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JSF 2.0.9上运行,Weblogic 10.3.4。我们现在正在生产环境中运行JSF,但遇到了会话复制和故障转移的一些问题。我们正在为我们的bean使用viewcope,并确保它们是Serializable / transient,并且瞬态变量实际上是无状态的。但是会话故障转移不起作用。我已经做了大量的测试并设法通过在web.xml中设置以下参数来使其工作

Running on JSF 2.0.9, Weblogic 10.3.4. We're now running JSF in our production environment but have encountered some issues with Session Replication and fail over. We are using viewscope for our beans and I have ensured they are Serializable/transient and that the transient variables are effectively stateless. However session fail over is not working. I have done extensive testing and managed to get it working by setting the following params in web.xml

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


    <context-param>
        <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
        <param-value>false</param-value>
    </context-param>

如果我将 STATE_SAVING_METHOD 设置为 server 我在故障转移时遇到了一个viewexpired异常。如果我将 client 设置为 PARTIAL_STATE_SAVING true 我得到以下错误:

If I set STATE_SAVING_METHOD to server I get a viewexpired exception on failover. If I set to client with PARTIAL_STATE_SAVING to true I get the following error:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at javax.faces.component.AttachedObjectListHolder.restoreState(AttachedObjectListHolder.java:165)
    at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1433)
    at com.sun.faces.application.view.StateManagementStrategyImpl$1.visit(StateManagementStrategyImpl.java:265)
    at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1507)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1521)
    at com.sun.faces.component.visit.VisitUtils.doFullNonIteratingVisit(VisitUtils.java:75)
    at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:282)
    at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:181)
    at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:448)
    at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:187)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:111)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:508)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:27)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57)
    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3730)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

所以我的问题是:


  • STATE_SAVING_METHOD - 客户& PARTIAL_STATE_SAVING - false 我唯一能让故障转移工作的方法是什么?

  • 客户/假组合的成本是多少。这个内存/ cpu是否广泛?

  • 这是一个错误,如果是这样,它在2.1或2.2中得到解决?

  • Is STATE_SAVING_METHOD - client & PARTIAL_STATE_SAVING - false the only way I'm going to get failover to work?
  • What is the cost of client/false combination. Is this memory/cpu extensive?
  • Is this a bug and if so is it resolved in 2.1 or 2.2?

提前致谢。

推荐答案

我终于得到了这个工作但不是没有一些额外的位和bobs。首先,我将以下内容添加到web.xml中(肯定是拼写错误):

I finally got this working but not without some extra bits and bobs. Firstly I added the following to the web.xml (yes agressive is spelled incorrectly):

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

客户端保存现在是服务器,部分状态保存仍然是假的(真的根本不起作用) )

The client saving is now server and partial-state saving is false still (true simply doesn't work)

其次,在实现HttpSessionAttributeListener后,我发现 com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap 哪个在会话中保持状态仅添加一次并且从未删除/添加/替换。因此,虽然它在本地会话中进行了更新,但这些更改从未复制到第二个jvm。 Weblogic文档声明必须在会话属性上调用setAttribute才能使复制正常工作。为了解决这个问题,我创建了一个阶段监听器,如下所示:

Secondly after implementing a HttpSessionAttributeListener I discovered that the com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap which holds the state in the session only got added once and never removed/added/replaced again. Therefore although it was being updated in the local session these changes were never replicated to a second jvm. Weblogic docs state that setAttribute must be called on session attributes for replication to work. To fix this I created a phase listener as follows:

public class ViewPhaseListener implements PhaseListener {

    public void afterPhase(PhaseEvent phaseEvent)
    {

    }

    public void beforePhase(PhaseEvent phaseEvent)
    {
        HttpServletRequest request = ((HttpServletRequest) phaseEvent.getFacesContext().getExternalContext().getRequest());
        HttpSession session = request.getSession();

        session.setAttribute("com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap", session.getAttribute("com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap"));

    }

    public PhaseId getPhaseId()
    {
        return PhaseId.RENDER_RESPONSE;
          //To change body of implemented methods use File | Settings | File Templates.
    }
}

这只是在每次请求后替换属性并确保它复制。另外一点,我使用以下内容限制存储在视图中的数据:

This simply replaces the attribute after each request and ensures it replicates. As an additional point I am limiting the data stored in the views with the following:

<context-param>
        <param-name>com.sun.faces.numberOfViewsInSession</param-name>
        <param-value>3</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.numberOfLogicalViews</param-name>
        <param-value>1</param-value>
    </context-param>

希望这可以帮助任何有相同问题的人。

Hope this helps anyone with the same issues.

这篇关于JSF会话故障转移和部分状态保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆