Clustering and Load Balancing of vaadin application (Urgent)

Dear All,
I am working on clustering and load balancing of vaadin application from last month.
Session Replication is not happening correctly.
Existing Environment Details :

  1. Apache Server is hosted on machine1 for load balancing
    I have configured everything which is required for failover and load balacing and works fine also.
    like worker.properties (mod_jk) , httpd.conf etc.
  2. app1 with tomcat is hosted on machine2
  3. same app1 with tomcat is also hosted on machine3 for load balancing and fail over
    I have configured everything what is required for clustering like implementation of serializable interface , updating of server.xml (port , SimpleTcp Cluster Configurations , add tag in web.xml for both application etc).
    I have simple vaadin application which is displayed combobox and clicking on combox item , one test message will displayed on other page.
    Problem :
    When I shut down machine 2 , then ideally session should be replicated to machine 3 so after refresh the application session should not be expired and page should be displayed i.e. same test message what previously was displayed.
    But every time I am getting vaadin default message in red color “Session Expired” when i shutdown one node.
    On tomcat log , below message is printed.
    “Response has been commited, session expired” - I dont know from where vaadin api commit the reponse when tomcat instance is down.
    Simple jsp based application is working fine , i m getting session expired on vaadin based app only.
    As per some comments received from vaadin group , i had also implemented tomcat valve still it is not working .
    Please help.
    Looking forward to your prompt response.

Regards,
Ashish Patel

First thing to ensure is that your application serializes properly:

  • Deploy your application to a tomcat configured with defaults
  • Use your application and move it to some state you recognize
  • Shutdown tomcat (to serialize the app)
  • Start the tomcat again (to deserialize the app)
  • Reload the page in your browser - does application stay in the state or restart?

A trivial test app:

package com.example.state;

import java.io.Serializable;

import com.vaadin.Application;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;

public class StateApplication extends Application implements Serializable {
	private static final long serialVersionUID = 1L;

	@Override
	public void init() {
		Window mainWindow = new Window("State Test Application");
		final Label label = new Label("");
		mainWindow.addComponent(label);
		mainWindow.addComponent(new Button("Change state", new Button.ClickListener() {
			private static final long serialVersionUID = 1L;

			public void buttonClick(ClickEvent event) {
				label.setValue("State = " + System.currentTimeMillis() % 1000);
			}
		}));
		setMainWindow(mainWindow);
	}
}

Dear Joonas,

Thanks for prompt response.
I followed the instuction by you. Still not getting any success. state has been changed at every time when tomcat instance is up and down.
Please find attached file for your reference.

Please suggest how to achieve session replication.

Please show Cluster block in your server.xml

Please find cluster block for both machine.
I have deployed same test application on machine 1 and machine2.
I have configured load balancer in below way (in apache server - worker.properties):
→ When tomcat instance on machine 1 is down then machine 2 will pick up request and vice versa.

In below both files , in cluster block only port is different (4001 and 4002)

=================== In Machine1 - server.xml ===============================

      <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="auto"
                  port="4001"
                  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"/>
      </Channel>

      <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.jpg;.*\.png;.*\.js;.*\.htm;.*\.html;.*\.txt;.*\.css;"/>		 
      <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

      <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                tempDir="/tmp/war-temp/"
                deployDir="/tmp/war-deploy/"
                watchDir="/tmp/war-listen/"
                watchEnabled="false"/>

      <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
      <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
================================================================================

====================== In Machine2 - server.xml=====================

      <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="auto"
                  port="4002"
                  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"/>
      </Channel>

      <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.jpg;.*\.png;.*\.js;.*\.htm;.*\.html;.*\.txt;.*\.css;"/>		 
      <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

      <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                tempDir="/tmp/war-temp/"
                deployDir="/tmp/war-deploy/"
                watchDir="/tmp/war-listen/"
                watchEnabled="false"/>

      <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
      <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
================================================================================

Based on this
description
I use this configuration in server.xml:


<Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve" enabled="true" sessionIdAttribute="takeoverSessionid"/>             

and


<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                 managerClassName="org.apache.catalina.cluster.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 useDirtyFlag="true"
                 notifyListenersOnReplication="true">

I have cluster working, but not in the vaadin application

Dear Joonas,
Please help.

Regards,
Ashish Patel

Dear Andris,

Please suggest if you have any other solutions.
No one has gave solutions yet.
It is very high priority for me.

I had tried with all possible ways but still can not get success.

I would really appreciate on your help.

Regards,

Hello, Ashish!

I want to say that I do not use vaadin application in a production mode, until only in test mode. Presently i have 2 jboss & 2 tomcat servers in a production, which work in cluster mode without apache(I use DNS + round robin). Application: ejb+jsp.

Tomcat cluster configuration does not differ from your, only what I mentioned above.

If my advice did’t help you, show completely server.xml

Dear Andris,

Please find server.xml for both machine 1 and machine2.
11572.xml (8.88 KB)
11573.xml (8.97 KB)

Value of attribute jvmRoute must be unique for each node of the cluster. Look
here
and
here

Dear Andris,
Thank u very much for prompt response.

But i have some confusion when load balancer comes in to picture.

Please find worker.properties(C:\www\Apache2\conf\worker.properties) file for your information.

worker.list=node1,node2,loadbalancer,jkstatus

Define a worker using ajp13

worker.node1.port=1111
worker.node1.host=192.168.100.166
worker.node1.type=ajp13
worker.node1.lbfactor=50

Define preferred failover node for node1

worker.node1.redirect=node2

Define another worker using ajp13

worker.node2.port=2222
worker.node2.host=192.168.100.167
worker.node2.type=ajp13
worker.node2.lbfactor=100

Disable node2 for all requests except failover

worker.node2.activation=disabled

Define the LB worker

worker.loadbalancer.type=lb
worker.loadbalancer.sticky_session=True
worker.loadbalancer.balance_workers=node1,node2

Define a ‘jkstatus’ worker using status

worker.jkstatus.type=status

====================================
node1 and node2 is jvmRoute name in server.xml file (machine1 and machine2).

and in httpd.conf :

Where to find workers.properties

Update this path to match your conf directory location

JkWorkersFile conf/workers.properties

Where to put jk logs

Update this path to match your logs directory location

JkLogFile logs/mod_jk.log

Set the jk log level [debug/error/info]

JkLogLevel info

Select the log format

JkLogStampFormat "[%a %b %d %H:%M:%S %Y]
"

JkOptions indicate to send SSL KEY SIZE,

JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

JkRequestLogFormat set the request format

JkRequestLogFormat “%w %V %T”

Send everything for context /ws to worker ajp13

JkMount /* loadbalancer

====================================

Please correct me if my understanding is not correct.
If i change node2 to node1 in server.xml (Machine 2) , then might be load balancer will not work.
I am checking and will get back to you with result.

Regards,

Are you sure that it generally works?

I not see in your conf file

LoadModule jk_module modules/mod_jk.so

Dear Andris,
I already added this line :

LoadModule jk_module modules/mod_jk.so and also added in module folder also.

Did you try the test app with a tomcat in the default configuration? It works for me.

Dear Joonas,

What is the meaning of tomcat default configurations ?

Regards,

I meant the configuration you get when you unzip the tomcat distribution package, drop war in webapps and run bin/startup.sh

Dear Joonas,

Thanks for prompt response.

It is working for normal jsp application.
but for vaadin application , it is not workin.

I would really appreciate if you send me vaadin sample demo on which you have implemented clustering.

Thanks and Regards,

Hi,

I am also facing the similar kind of issue.

I have deployed the war file in 2 machines to check the laod balancing, if i stop any one machine it is working fine.
If i start both the machines, for sometime the URL is working fine after that i am getting null pointer exception after clciking on any action and session value is null.

Can anyone please help in resolving this issue.

Thanks,
Madhuri