|
|
Line 16: |
Line 16: |
| | | |
| ==Software== | | ==Software== |
− | *We will investigate various levels of networking scenarios that link our distributed JVM nodes.
| |
− | ===Base Case 1: Custom Distributed RMI===
| |
− | *Using RMI via for example the '''t3''' protocol is not recommended for production enterprise applications - we describe a simple use case here only for historical reference.
| |
− | ====EE Distributed Session Bean====
| |
− | *Deploy this on each of your WebLogic servers
| |
− | <source lang="java">
| |
− | @Stateful(mappedName="ejb/Node")
| |
− | @Local
| |
− | public class Node implements NodeRemote, NodeLocal {
| |
− | private int transition;
| |
− | private int state;
| |
− |
| |
− | public void setState(int aState) {
| |
− | System.out.println("_Distributed: new state: " + aState);
| |
− | state = aState;
| |
− | }
| |
− |
| |
− | public int getState() {
| |
− | return state;
| |
− | }
| |
− |
| |
− | public int getAdjacent(int offsetX, int offsetY) {
| |
− | return 1;
| |
− | }
| |
− | }
| |
− |
| |
− | @Remote
| |
− | public interface NodeRemote {
| |
− | //####<15-Sep-2010 1:21:15 o'clock PM EDT> <Info> <EJB> <xps435> <AdminServer> <[STANDBY] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1284571275760> <BEA-010009>
| |
− | //<EJB Deployed EJB with JNDI name org_eclipse_persistence_example_distributed_ClientEARorg_eclipse_persistence_example_distributed_ClientEJB_jarNode_Home.>
| |
− | public void setState(int state);
| |
− | public int getState();
| |
− | public int getAdjacent(int offsetX, int offsetY);
| |
− | }
| |
− |
| |
− | </source>
| |
− | ====SE client====
| |
− | *Run this on one of the servers or a separate SE JVM
| |
− | <source lang="java">
| |
− | package org.eclipse.persistence.jmx;
| |
− |
| |
− | import java.util.ArrayList;
| |
− | import java.util.HashMap;
| |
− | import java.util.Hashtable;
| |
− | import java.util.List;
| |
− | import java.util.Map;
| |
− |
| |
− | import javax.naming.Context;
| |
− | import javax.naming.InitialContext;
| |
− | import javax.rmi.PortableRemoteObject;
| |
− |
| |
− | import org.eclipse.persistence.example.distributed.NodeRemote;
| |
− |
| |
− | /**
| |
− | * This class tests RMI connections to multiple WebLogic servers running on
| |
− | * remote JVM's. It is intended for experimental concurrency investigations only.
| |
− | * @author mfobrien 20100916
| |
− | *
| |
− | */
| |
− | public class JNDIClient {
| |
− | public static final List<String> serverNames = new ArrayList<String>();
| |
− |
| |
− | private Map<String, Hashtable<String, String>> contextMap = new HashMap<String, Hashtable<String, String>>();
| |
− | private Map<String, Context> rmiContextMap = new HashMap<String, Context>();
| |
− | private Map<String, NodeRemote> remoteObjects = new HashMap<String, NodeRemote>();
| |
− | private Map<String, Integer> stateToSet = new HashMap<String, Integer>();
| |
− | private static Map<String, String> serverIPMap = new HashMap<String, String>();
| |
− |
| |
− | private static final String CONTEXT_FACTORY_NAME = "weblogic.jndi.WLInitialContextFactory";
| |
− | private static final String SESSION_BEAN_REMOTE_NAME = "ejb/Node#org.eclipse.persistence.example.distributed.NodeRemote";
| |
− | //private String sessionBeanRemoteName = "java:comp/env/ejb/Node"; // EE only
| |
− | //private String sessionBeanRemoteName = "org_eclipse_persistence_example_distributed_ClientEARorg_eclipse_persistence_example_distributed_ClientEJB_jarNode_Home" ;
| |
− |
| |
− | /**
| |
− | * For each server add the name key and corresponding RMI URL
| |
− | */
| |
− | static {
| |
− | // Beowulf5 on Cat6 1Gb/Sec
| |
− | serverNames.add("beowulf5");
| |
− | serverIPMap.put("beowulf5", "t3://192.168.0.165:7001");
| |
− | // Beowulf6 on Cat6 1Gb/Sec
| |
− | serverNames.add("beowulf6");
| |
− | serverIPMap.put("beowulf6", "t3://192.168.0.166:7001");
| |
− | }
| |
− |
| |
− | public JNDIClient() {
| |
− | }
| |
− |
| |
− | public void connect() {
| |
− | /**
| |
− | * Note: only import weblogic.jar and naming.jar
| |
− | */
| |
− | // For JNDI we are forced to use Hashtable instead of HashMap
| |
− | // populate the hashtables
| |
− | for(String aServer : serverNames) {
| |
− | Hashtable<String, String> aTable = new Hashtable<String, String>();
| |
− | contextMap.put(aServer,aTable);
| |
− | aTable.put(Context.INITIAL_CONTEXT_FACTORY,CONTEXT_FACTORY_NAME);
| |
− | aTable.put(Context.PROVIDER_URL, serverIPMap.get(aServer));
| |
− | }
| |
− |
| |
− | /**
| |
− | * Setup and connect to RMI Objects
| |
− | */
| |
− | try {
| |
− | // Establish RMI connections to the session beans
| |
− | for(String aServer : serverNames) {
| |
− | Context aContext = new InitialContext(contextMap.get(aServer));
| |
− | rmiContextMap.put(aServer, aContext);
| |
− | System.out.println("Context for " + aServer + " : " + aContext);
| |
− | // For qualified name look for weblogic log "EJB Deployed EJB with JNDI name"
| |
− | Object aRemoteReference = aContext.lookup(SESSION_BEAN_REMOTE_NAME);
| |
− | System.out.println("Remote Object: " + aRemoteReference);
| |
− | NodeRemote aNode = (NodeRemote) PortableRemoteObject.narrow(aRemoteReference, NodeRemote.class);
| |
− | remoteObjects.put(aServer, aNode);
| |
− | System.out.println("Narrowed Session Bean: " + aNode);
| |
− | // initialize state list
| |
− | stateToSet.put(aServer, new Integer(0));
| |
− | }
| |
− |
| |
− | NodeRemote aNode;
| |
− | StringBuffer aBuffer = new StringBuffer();
| |
− | // Endlessly generate RMI requests
| |
− | for(;;) {
| |
− | // Send messages to entire grid in parallel
| |
− | for(String remoteServer : remoteObjects.keySet()) {
| |
− | aNode = remoteObjects.get(remoteServer);
| |
− | // increment server's pending state
| |
− | stateToSet.put(remoteServer, stateToSet.get(remoteServer).intValue() + 1);
| |
− | aNode.setState(stateToSet.get(remoteServer));
| |
− | aBuffer = new StringBuffer("State from: ");
| |
− | aBuffer.append(remoteServer);
| |
− | aBuffer.append(" = ");
| |
− | aBuffer.append(aNode.getState());
| |
− | System.out.println(aBuffer.toString());
| |
− | }
| |
− | }
| |
− | } catch (Exception e) {
| |
− | e.printStackTrace();
| |
− | }
| |
− | }
| |
− |
| |
− | public static void main(String[] args) {
| |
− | JNDIClient client = new JNDIClient();
| |
− | client.connect();
| |
− | }
| |
− | }
| |
− | </source>
| |
− |
| |
− | ===OTS 1: EclipseLink Cache Coordination===
| |
− | ===OTS 2: TopLink Grid (uses Coherence)===
| |
− | *We will investigate using Oracle Coherence as a distributed 2nd level cache. Before we start we will verify the Coherence install that ships with certain versions of WebLogic (before using it from our JPA application).
| |
− | ====Coherence Quickstart====
| |
− | *Here we verify Coherence 3.6 by installing and running the Coherence example installed as an option in the WebLogic server 11gR1 install.
| |
− | =====Distributed Coherence Cache Example - 4 caches=====
| |
− | *In the following image we see the messaging that occurs '''out-of-the-box''' via cache discovery when running Coherence on multiple distributed JVM's on different machines.
| |
− | **We start the nodes in the following order 192.168.0.'''194''',192.168.0.'''191''',192.168.0.'''166''',192.168.0.'''165''',
| |
− | *See '''$WEBLOGIC_HOME\coherence_3.6\examples\java\bin'''
| |
− | *[[Image:Coherence_4_caches_infinite_message_loop_3_57.JPG]]
| |
| | | |
| ==Hardware== | | ==Hardware== |