Niepowodzenie sesji JSF i Częściowe zapisywanie stanu

Działa na JSF 2.0.9, Weblogic 10.3.4. Obecnie uruchamiamy JSF w naszym środowisku produkcyjnym, ale napotkaliśmy pewne problemy z replikacją sesji i zawiedliśmy. Używamy viewscope dla naszych fasoli i zapewniłem, że są Serializowalne / przejściowe i że zmienne przejściowe są skutecznie bezpaństwowe. Jednak session fail over nie działa. Zrobiłem obszerne testy i udało się go uruchomić, ustawiając następujące paramy w Internecie.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>

If I set STATE_SAVING_METHOD do server dostaję wyjątek viewexpired przy przełączaniu awaryjnym. Jeśli ustawiłem na client z PARTIAL_STATE_SAVING na true otrzymuję następujący błąd:

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)

Więc moje pytania są takie:

  • jest STATE_SAVING_METHOD - client & PARTIAL_STATE_SAVING - false to jedyny sposób, żeby uruchomić przełącznik awaryjny?
  • jaki jest koszt połączenia klient / fałsz. Czy ta pamięć / procesor jest obszerna?
  • czy jest to błąd i jeśli tak to jest rozwiązany w 2.1 lub 2.2?
Z góry dzięki.
Author: BalusC, 2012-08-23

2 answers

W końcu to działa, ale nie bez dodatkowych bitów i bobów. Po pierwsze dodałem do sieci:xml (tak jest napisane niepoprawnie):

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

Zapisywanie klienta jest teraz serwerem, a zapisywanie stanu częściowego jest nadal false (true po prostu nie działa)

Po Drugie po zaimplementowaniu HttpSessionAttributeListener odkryłem, że com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap, który utrzymuje stan w sesji, został dodany tylko raz i nigdy więcej nie został usunięty/dodany/zastąpiony. Dlatego chociaż był aktualizowany w sesji lokalnej zmiany te nigdy nie były replikowane do drugiego jvm. Dokumenty Weblogic stwierdzają, że setAttribute musi być wywołany na atrybutach sesji, aby replikacja działała. Aby to naprawić utworzyłem słuchacz fazy w następujący sposób:

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.
    }
}

To po prostu zastępuje atrybut po każdym żądaniu i zapewnia jego replikację. Jako dodatkowy punkt ograniczam dane przechowywane w widokach o następującej treści:

<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>
Mam nadzieję, że to pomoże każdemu z tymi samymi problemami.
 12
Author: andyfinch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-12 09:40:44

Replikacja sesji powinna być obsługiwana przez load balancer, ponieważ aplikacja JSF jest świadoma tylko kontekstu na węźle, do którego jest wdrożona. W związku z tym nie powinno mieć znaczenia, czy ustawisz STATE_SAVING_METHOD na client lub server.

Wydaje mi się, że masz nieprawidłową konfigurację load balancer. Jeśli używasz serwera HTTP Apache jako serwera proxy, zobacz poniższy link, aby uzyskać więcej informacji na temat sesji lepkość:

Http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html

Zalecałbym ustawienie ProxySet stickysession=ROUTEID i sprawdzić, czy to rozwiązuje problem.

 0
Author: p_strand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-06 17:25:39