0

ZK Clustering, Session Replication Question [closed]

asked 2013-01-22 16:46:26 +0800

carpolva gravatar image carpolva
155 4

updated 2013-01-23 01:54:43 +0800

jimyeh gravatar image jimyeh
2047 1 4
ZK Team

Hi !!

I'm working on a very basic zk example deploying it in a clustered architecture with 3 Tomcat nodes. I will omit all the Apache Web Server and Tomcat cluster configuration.

In my web.xml I have the following tag in order to activate session exchange:

<distributable/>

In my zk.xml I have the following (more details about ZK Clustering in ZK Tomcat Clustering Part II):

<system-config>
    <ui-factory-class>org.zkoss.zk.ui.http.SerializableUiFactory</ui-factory-class>
</system-config>

Here is part of my .zul page:

<label id="myLabel" value="0"/>
<button label="Generate Value" forward="onClick=onClickGenerate()"/>
<button label="Read Value" forward="onClick=onClickRead()"/>

This is the associated java bean:

public class MyBean extends GenericForwardComposer implements Serializable {
       private Label myLabel;

       public void doAfterCompose(Component comp) {
              try {
                  super.doAfterCompose(comp);
              } catch (Exception e) {e.printStackTrace();}
       }

       public void onClickGenerate(ForwardEvent event){
              System.out.println("onClickGenerate invoked");
              myLabel.setValue("XXXXXXX");
       }

       public void onClickRead(ForwardEvent event){
              System.out.println("Label value: " + myLabel.getValue());
       }
}

I deploy the .war file in each Tomcat node, I start the Apache Web Server and each Tomcat node.

The following is a test case:

When page loads, the label default value is "0". Then I press the "Generate Value" button, so the "onClickGenerate" method is invoked in the java bean and the label value is updated to "XXXXXXX". Looking at the Tomcat console I can see that Tomcat Node 1 processed this request because the output "onClickGenerate invoked" appeared in this node's console right?.

Next step, I press the "Read Value" button... if the same Tomcat node processes this new request, the output will be the following: "Label value: XXXXXXX".

BUT... if a different Tomcat node processes this new request, the output will be the following: "Label value: 0".

What does it mean?, that only in the first Tomcat node which processed the "onClickGenerate" the label's value was updated, but this label's value was not replicated with its updated value to the other Tomcat nodes, so... if a different Tomcat processes a new request in order to read the label's value, that value is not updated and remains with its default value. I want to know what should I do in order to give each Tomcat node the ability to know session data no matter which Tomcat processes the request, if Tomcat 1 updated the label's value the other Tomcat nodes must know this updated value too, is this possible right?.

I hope I made me understand. it's a simple zk clustering case but I'm still learning.

Any help will be appreciated, thank you very much!!

Best regards.

delete flag offensive retag edit

The question has been closed for the following reason "the question is answered, right answer was accepted" by sjoshi
close date 2013-02-08 06:40:10

2 Answers

Sort by ยป oldest newest most voted
5

answered 2013-01-22 17:23:05 +0800

gekkio gravatar image gekkio flag of Finland
899 1
http://gekkio.fi/blog

Try including the ClusterSessionPatch listener. The Javadoc is slightly misleading, because the listener is not only for Weblogic/cloud environments, but for all session replication where the replication process depends on certain assumptions.

Just in case someone is interested, here's a more in-depth technical description:

The ZK session (which includes the desktops, and thus all pages and components) is stored in a single native session attribute. This means that when the session is first created, ZK will internally do a method call like this: httpSession.setAttribute("somekey", zkSession);

When things happen in the ZK app, the components/composers/desktops/stuff inside the session will be changed by using mutation methods (e.g. label.setValue). This means that no httpSession methods will be called, but the ZK objects will be modified directly.

Now, when session replication is used, most servlet containers optimize the process so that session are not serialized/deserialized if nothing has changed. This means that the container will count calls to httpSession.setAttribute and other methods which change the native session. It cannot detect if the attribute values are changed internally, because that would be very expensive and difficult to implement.

So, if you call label.setValue, the label will be modified but no native session methods are called and the container doesn't do any replication. ClusterSessionPatch fixes this by automatically calling httpSession.setAttribute("somekey", zkSession) again on every request. This informs the container that the ZK session has changed, and the container will handle replication correctly.

link publish delete flag offensive edit
0

answered 2013-01-22 20:49:39 +0800

carpolva gravatar image carpolva
155 4

Hi Gekkio.

Thank you very much!, that's exactly what I needed. I see that in ZK clustering in Tomcat (Tutorial) this listener is not mentioned, but that tutorial was made in 2007 (using Tomcat 5)... maybe something in the specification has changed and now that listener is required (I'm using Tomcat 6 and ZK 6.5).

Best regards.

link publish delete flag offensive edit

Comments

Hi, It will be better if you could post this kind information(not a answer) as a comment, or add to the bottom of the question as a extra information

dennis ( 2013-01-23 08:31:45 +0800 )edit

Hi Dennis, thanks... I will take it into account.

carpolva ( 2013-01-23 13:48:09 +0800 )edit

Question tools

Follow
1 follower

RSS

Stats

Asked: 2013-01-22 16:46:26 +0800

Seen: 69 times

Last updated: Jan 22 '13