payara / Payara

Payara Server is an open source middleware platform that supports reliable and secure deployments of Java EE (Jakarta EE) and MicroProfile applications in any environment: on premise, in the cloud or hybrid.
http://www.payara.fish
Other
882 stars 304 forks source link

Session replication #1171

Closed stePrime closed 7 years ago

stePrime commented 7 years ago

Session replication doesn' t work on all nodes

I created a simple cluster with 3 nodes on LAN The host names of the nodes have been renamed as "n1.test.com","n2.test.com","n3.test.com" I enabled Hazelcast on the cluster config and i selected "Hazelcast" as persistence type on the Web container Availability tab. In the application :

The n1 and n2 nodes works well ,indeed when i open or/and refresh a page on these nodes the session is shared and is the same. When i load the page on the third node the session is destroyed and re-created.

mikecroft commented 7 years ago

Have you confirmed that the nodes are definitely clustering together? You should see Hazelcast cluster member information in the logs. It sounds like n3 is simply not joining the cluster, hence it has no knowledge of the session and creates you a new one. Could you attach some of your network configuration and how you have configured Hazelcast beyond the default? (if at all)

lprimak commented 7 years ago

Is this an Ajax application by any chance?

stePrime commented 7 years ago

About network configuration we use static ip and in hosts file i added ip address and hostname of each nodes. that's it. The application use JSF but doesn't use Ajax, it shows only the SessionID on the index.xhtml.

My web.xml file :

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <distributable/>

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

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

My glassfish-web.xml file:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">

<glassfish-web-app error-url="">

    <context-root>/testSession</context-root>
    <class-loader delegate="true"/>
    <jsp-config>
        <property name="keepgenerated" value="true">
            <description>Keep a copy of the generated servlet class' java code.</description>
        </property>
    </jsp-config>
    <session-config>
        <cookie-properties>
            <property name="cookieDomain" value="test.com"/>
        </cookie-properties>
        <session-manager persistence-type="hazelcast"> 
            <manager-properties> 
                <property name="persistenceFrequency" value="web-method" /> 
            </manager-properties> 
            <store-properties> 
                <property name="persistenceScope" value="session" /> 
            </store-properties> 
        </session-manager> 
    </session-config>
</glassfish-web-app>

Cluster Log: clusterlog

Cluster in running... cluster

Hazelcast configuration: hazelcastconfig

"Web Container Availability" configuration: wca

"EJB Container Availability" configuration (but i don't use): eca

Steps of application:

Step 1: cin

Step2: cfin

Thanks for the support.

mikecroft commented 7 years ago

Hazelcast clustering works differently to the clustering methods in the admin console. You don't need to create a cluster like that, standalone instances work fine.

What has happened is that Shoal is clustering your 3 instances, and the message you've screenshotted from the logs is a GMS cluster message, which is a Shoal component and nothing to do with Hazelcast.

I suspect that there is still some misconfiguration somewhere along the line here. From your screenshot, it appears that n1 and n2 are both on the same server, whereas n3 may be remote, is that correct?

I also notice that the session ID in all three screenshots is exactly the same, which would indicate that it is probably working.

OndroMih commented 7 years ago

As @mikecroft explained, you seem to have configured clustering the old way using "cluster" configuration. With Hazelcast, the clustering in Payara Server is configured in a different way. Instead of a "cluster", you need to setup standalone instances based on the same copy of configuration and turn on Hazelcast. This blog post about hazelcast clustering describes the steps to follow. We are working on improving the web console to make the configuration more user friendly and straightforward.

If you want to use the new way of clustering, you should completely delete your cluster configuration and create a new setup according to the blog post. Otherwise you end up with an old way of clustering where Hazelcast is not used in any way, even if you turn it on and configure it properly.

stePrime commented 7 years ago

Hi Team,

Thanks a lot for the support.

I also tried to create cluster as standalone instances but the result was the same. As usual in these cases the problem was a stupid thing: n3 time was not synchronized with other nodes and this was causing invalidation of the session. Sorry for my oversight.

But the problem come back when I added Primefaces (library for JSF) tag in the page, hence sometimes when I refresh page the session change.

Have you any ideas ?

mikecroft commented 7 years ago

Interesting. Are there any relevant log messages?

stePrime commented 7 years ago

No, nothing relevant log messages.

If it would help you, I add this code in web.xml to fix a ViewExpiredException ("ERROR: MAC did not verify!") in cluster environment:

`

jsf/ClientSideSecretKey
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>OaHMhbhnoH7qZYA/AmGEBg==</env-entry-value>

`

lprimak commented 7 years ago

Just FYI, I have never had success with the following:

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

in the past.

I would suggest you stick with server based saved sessions. This may also solver your issue

stePrime commented 7 years ago

@lprimak, I tried it ma does not work. The session change frequently.

lprimak commented 7 years ago

Have you, by any chance deploying the app itself without availability enabled? i.e. you need to use asadmin deploy --availabilityenabled

Also, make sure you have this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  <session-config>
    <session-manager persistence-type="hazelcast">
      <manager-properties>
        <property name="relaxCacheVersionSemantics" value="true"/>
      </manager-properties>
    </session-manager>
  </session-config>
</glassfish-web-app>

as described here: http://blog.payara.fish/payara-server-rolling-upgrades

mikecroft commented 7 years ago

You can also turn on availability with a checkbox when you deploy through the admin console. Note that this is not enabled by default.

stePrime commented 7 years ago

Availability was enabled. I added "relaxCacheVersionSemantics" property in glassfish-web.xml and it seems to work fine.

Next step is to add WebSockets.

Thanks a lot for the support.

lprimak commented 7 years ago

Fantastic. Can we close this issue? I think we should open one to get relaxCacheVersionSemantics to be enabed by default