How smart the ha-jndi proxy is and how to use the ha-jndi smart proxy smartly.
thunder.farmer Jan 12, 2011 1:22 AMAfter two days' experiment, I think I get to know what happens exactly behind the scene about the ha-jndi smart proxy.
Here I give out my understanding about the myth.
I am talking about the scenario that standalone client runs in the different jvm.
Any corrections or different understandings are welcome.
In short, the ha-jndi proxy will NOT get updated about the cluster's changes unitl it connects to server.
That means the smart proxy will get to know any change of cluster only when you perform lookkup.
Say, there are 3 nodes in the cluster NodeA, NodeB and NodeC and all the nodes are live.
you initialize the JNDI context like this:
Hashtable jndiEvn = new Hashtable();
jndiEvn.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
jndiEvn.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
jndiEvn.put(Context.PROVIDER_URL, "jnp://NodeA:1100,jnp://NodeB:1100,jnp://NodeC:1100");
ctx = new InitialContext(jndiEvn);
Currently the proxy create a rmi connection to the NodeA.
So if we shutdown NodeB or NodeC and then perform a lookup, everything is fine.
And after the lookup, the ha-jndi proxy realize that the NodeB or NodeC is down.
But if you shutdown the NodeA which the proxy is currently connecting to, and then perform lookup, you will get CommunicationException caused by the scoet connection refused.
Apparently the proxy is still trying to connect to NodeA.
Don't be disappointed by the exception!
Yes, you get an exception, but the same time you get a more smart proxy.
Now the ha-jndi know the NodeA is down and turn to other live Nodes.
So if you lookup the same jndi second, you will get it without any issue.
So the conclusion is that if you want to achieve transparent failover, you need to do some extra work in your code to deal with extreme situaction where the node that proxy is currently connecting to is down.
So the code should be like this:
try {
// lookuping will fail because the server which ha-jndi is currently connecting to is shutdown
// but the ha-jndi smart proxy get a chance to to be updated about the cluster's changes.
// next time, it will connect to the other server.
ejbRemote = ctx.lookup(jndiName);
} catch (NamingException nex) {
// this time, everything works fine because the ha-jndi proxy get updated from the last failure.
try {
ejbRemote = ctx.lookup(jndiName);
} catch (NamingException nex2) {
nex.printStackTrace();
}
}
A more interesting thing is that creating a new InitialContext doesn't resolve the problem above.
I mean that if you try to get an uptodate ha-jndi proxy by creating a new jndi context for every lookup, it doesn't work.
Seems the proxy get downloaded for the first time when jndi context is created.
For e.g:
Hashtable jndiEvn = new Hashtable();
jndiEvn.put(...)
IntialContext ctx = new IntialContext();
ctx.lookup(...)
Thread.currentThread().sleep(1 * 60 * 1000);
// during this period, current NodeA is down.
IntialContext ctx = new IntialContext();
ctx.lookup(...); // here still you will get an CommunicationException.
By creating a new ctx, you expect that the smart proxy knows the NodeA is down, but that's not it.
attach my code for refernce
Any comment is welcome.
-
thunder.zip 4.0 KB