Reputation: 11
I am developing an application with JDeveloper 11.1.1.6.0. I have a problem with my client application when I try to connect to a weblogic server from a cluster from within my application. A certain service runs on this server that I would like to call.
The situation is as follows:
There is a weblogic instance, whose configuration I cannot change at the moment. The weblogic instance has the following servers and clusters:
I am trying to connect to t3://A:2 and not to the cluster or any of the other two servers. However, it works only every third time, maybe because of the three servers within the cluster. The cluster uses unicast for messaging and round-robin-affinity for load balancing.
I am trying to find out what causes this. Can I change something within the configuration of the weblogic where my client application runs (integrated or standalone)? Or must the configuration setup of the instance with the server cluster be changed?
Thank you in advance!
Best Regards
(23.05.2013) EDIT:
We use a plain JNDI-Lookup to access an EJB on the remote server in the described scenario.
Context ctx = new InitialContext();
Object o = ctx.lookup(...)
...
jndi.properties:
java.naming.provider.url=t3://A:2 java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
It seems to be possible to send the JNDI-Request to the right server by setting the property PIN_TO_PRIMARY_SERVER. Yet, subsequent ejb-requests are still routed to the whole cluster using round robin...
Can we do something on client-side to change this behavior to always address the specific server with the url t3://A:2?
Upvotes: 1
Views: 3624
Reputation: 1749
I had a similar problem and after trying changing the InvocationContext environment properties, I found that I had very little luck. Instead I had to alter the weblogic-ejb-jar.xml for my stateless session bean.
String destination = "t3://node-alpha:2010";
Hashtable<String, String> env = new Hashtable<String, String>();
env.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put( Context.PROVIDER_URL, destination );
// env.put( weblogic.jndi.WLContext.ENABLE_SERVER_AFFINITY, "true" );
// env.put( weblogic.jndi.WLContext.PIN_TO_PRIMARY_SERVER, "true" );
InitialContext ctx = new InitialContext( env );
EJBHome home = (EJBHome) ctx.lookup( JNDI_REMOTE_SYSTEM_SF );
sf = SomeSf.class.cast( home.getClass().getMethod( "create" ).invoke( home ) );
// Check that we are hitting the right server node.
System.out.println( destination + " => " + sf );
Once you start a transaction, you shouldn't change servers, so I would create a stateless bean to receive the targeted calls and from there begin the work you intend to do. You can set a stateless bean as not clusterable in the weblogic-ejb-jar.xml
. You actually need to set both items listed below.
<home-is-clusterable>False</home-is-clusterable>
<stateless-bean-is-clusterable>False</stateless-bean-is-clusterable>
What this means is that when getting a reference through the initial context, is that the targeted server will give an instance of the reference to the stateless bean on that particular cluster node.
Using the servers
With home-is-clusterable
& stateless-bean-is-clusterable
set to true
Here the first entry is the server it is targeting, then the rest are for fail-over and/or the load balancing (e.g. round robin).
ClusterableRemoteRef(
3980825488277365621S:node-alpha:[2010,2010,-1,-1,-1,-1,-1]:MyDomain:node-alpha
[
3980825488277365621S:node-alpha:[2010,2010,-1,-1,-1,-1,-1]:MyDomain:node-alpha/338,
4236365235325235233S:node-alpha:[2011,2011,-1,-1,-1,-1,-1]:MyDomain:node-alpha/341,
1321244352376322432S:node-beta:[3010,3010,-1,-1,-1,-1,-1]:MyDomain:node-beta/342,
4317823667154133654S:node-beta:[3011,3011,-1,-1,-1,-1,-1]:MyDomain:node-beta/345
]
)/338
With home-is-clusterable
& stateless-bean-is-clusterable
set to false
weblogic.rmi.internal.BasicRemoteRef - hostID: '-3980825488277365621S:node-alpha:[2010,2010,-1,-1,-1,-1,-1]:MyDomain:node-alpha', oid: '336', channel: 'null'
weblogic-ejb-jar.xml example below.
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>SomeSf</ejb-name>
<stateless-session-descriptor>
<pool>
<max-beans-in-free-pool>42</max-beans-in-free-pool>
</pool>
<stateless-clustering>
<home-is-clusterable>false</home-is-clusterable>
<stateless-bean-is-clusterable>false</stateless-bean-is-clusterable>
<stateless-bean-methods-are-idempotent>true</stateless-bean-methods-are-idempotent>
</stateless-clustering>
</stateless-session-descriptor>
<transaction-descriptor>
<trans-timeout-seconds>20</trans-timeout-seconds>
</transaction-descriptor>
<enable-call-by-reference>true</enable-call-by-reference>
<jndi-name>SomeSf</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
Upvotes: 1