[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[rap-dev] Various issues running RAP in a clustered envorinment
|
Hello,
I wonder, is anybody using RAP on a session-replicated cluster?
For the last few days I was trying to get my RAP based project to play
nicely in a clustered environment.
However, after fixing all the application-related issues, I still see
strange behaviour, most likely caused by RAP.
The environment is rather tricky: 2x Tomcat application servers +
Apache+mod_jk round-robin load balancer
The load-balancer is alternating between the two Tomcat instances for
every request, which means high requirements regarding session
replication consistency.
Unfourtunately the environment is as-is, later the application has to
run in an environment behaving like this one.
RAP is configured with OperationMode.SESSION_FAILOVER and
<distributable/> and in principle, session replication seems to work.
Tomcat was configured with SimpleTcpCluster and channelSendOptions="6"
(synchrounous session replication with ACK - according to the tomcat
users mailing list the strictest setting Tomcat has.).
However even with the simple example below, I get strange behaviour
and issues: https://youtu.be/p5u2z-NjIs0
Sometimes request/response pairs are sent for 30s.
And for a larger real-world app I also get sometimes:
- HTTP-500 and HTTP-412
- ConcurrentModificationException during Session Serialization
(Collection is modified concurrently while being serialized)
- Various other exceptions listed below.
- ClientListener is not Serializeable
I had a look at RAP's source, but I am a bit lost:
* ClientListener not implementing Serializeable was easy to fix and
seems to work.
* I guess the ConcurrentModificationException during seerialization is
tough and it seems I am not the only one expoeriencing this:
https://www.eclipse.org/forums/index.php/t/532053/
I wrote my own servlet filter (running before/after RWTClusterSupport)
serializing all session attributes to disk, *removing* the attributes,
and re-loading them again at the next request and ran into issues of
UISessionImpl.attributes beeing empty. I saw
UISessionImpl.get/setAttribute is synchronized, is this supposed to be
accessed by multiple threads? If so, synchronization has no effect on
the app servers synchronization during session replication - it will
simply snapshot some inconsistent state).
* What could cause the client to immediatly re-execute a new request
after receiving a response? Maybe this could be a starting point to
debug the request/response storms I am experiencing.
Thank you in advance and best regards, Clemens
public class BasicEntryPoint extends AbstractEntryPoint {
protected void createContents(Composite parent) {
Tree tree;
ScrolledComposite scroll = new ScrolledComposite(parent, SWT.V_SCROLL);
tree = new Tree(scroll, SWT.BORDER);
scroll.setContent(tree);
scroll.setExpandHorizontal(true);
scroll.setExpandVertical(true);
tree.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent se) {
if(tree.getSelectionCount() > 0) {
TreeItem item = tree.getSelection()[0];
item.setText(item.getText() + "_");
}}
});
for(int i=0; i < 10; i++) {
TreeItem item = new TreeItem(tree, SWT.NONE);
item.setText("MainItem " + i);
for(int m=0; m < 10; m++) {
TreeItem childItem = new TreeItem(item, SWT.NONE);
childItem.setText("Child: "+m);
}
}
}
}
Tomcat cluster configuration:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
<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="192.168.56.102"
port="4000"
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=""/>
<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"/>
</Cluster>
- java.lang.NullPointerException
at org.eclipse.rap.rwt.SingletonUtil.getUniqueInstance(SingletonUtil.java:74)
at org.eclipse.rap.rwt.internal.lifecycle.RequestCounter.getInstance(RequestCounter.java:25)
at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.isRequestCounterValid(LifeCycleServiceHandler.java:133)
at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.processUIRequest(LifeCycleServiceHandler.java:94)
at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.synchronizedService(LifeCycleServiceHandler.java:75)
at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.service(LifeCycleServiceHandler.java:66)
at org.eclipse.rap.rwt.engine.RWTServlet.handleValidRequest(RWTServlet.java:135)
at org.eclipse.rap.rwt.engine.RWTServlet.handleRequest(RWTServlet.java:117)
at org.eclipse.rap.rwt.engine.RWTServlet.doPost(RWTServlet.java:107)
java.lang.NullPointerException
org.eclipse.swt.graphics.ImageSerializer.getResourceManager(ImageSerializer.java:95)
org.eclipse.swt.graphics.ImageSerializer.access$1(ImageSerializer.java:94)
org.eclipse.swt.graphics.ImageSerializer$PostDeserializationValidation$1.run(ImageSerializer.java:53)
org.eclipse.rap.rwt.internal.engine.PostDeserialization.runProcessors(PostDeserialization.java:28)
org.eclipse.rap.rwt.internal.engine.RWTClusterSupport.beforeService(RWTClusterSupport.java:62)
org.eclipse.rap.rwt.internal.engine.RWTClusterSupport.beforeService(RWTClusterSupport.java:53)
org.eclipse.rap.rwt.internal.engine.RWTClusterSupport.doFilter(RWTClusterSupport.java:41)
java.lang.NullPointerException
org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.shutdownUISession(LifeCycleServiceHandler.java:148)
org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.synchronizedService(LifeCycleServiceHandler.java:80)
org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.service(LifeCycleServiceHandler.java:66)
org.eclipse.rap.rwt.engine.RWTServlet.handleValidRequest(RWTServlet.java:135)
org.eclipse.rap.rwt.engine.RWTServlet.handleRequest(RWTServlet.java:117)
org.eclipse.rap.rwt.engine.RWTServlet.doPost(RWTServlet.java:107)
java.lang.NullPointerException
at org.eclipse.rap.rwt.internal.lifecycle.LifeCycleUtil.getSessionDisplay(LifeCycleUtil.java:37)
at org.eclipse.rap.rwt.internal.lifecycle.LifeCycleUtil.getSessionDisplay(LifeCycleUtil.java:31)
at org.eclipse.rap.rwt.internal.lifecycle.SimpleLifeCycle.execute(SimpleLifeCycle.java:48)
at org.eclipse.rap.rwt.internal.service.RWTMessageHandler.executeLifeCycle(RWTMessageHandler.java:57)
at org.eclipse.rap.rwt.internal.service.RWTMessageHandler.handleMessage(RWTMessageHandler.java:41)
at org.eclipse.rap.rwt.internal.remote.MessageChainElement.handleMessage(MessageChainElement.java:29