For the rest of this post, here will be 2 machines: glassfish1 and glassfish2. Glassfish1 will be the domain administration server (DAS) and will house g1-a1 (glassfish1, node-agent 1) as well as g1-i1 (glassfish1, instance1). Glassfish2 will only have g2-a1 (glassfish2, node-agent 1) and g2-i1 (glassfish2, instance2). In all of the commands below, I reference the machines by their hostname (glassfish1 or glassfish2). I am able to do this because I have edited /etc/hosts on both machines to provide a mapping from the hostnames glassfish1 and glassfish2 to the physical IP for those machines. If you have not done this, and if you do not have another setup for DNS resolution, you'll need to refer to the machines by their physical IP.
You'll need to grab the glassfish installer from https://glassfish.dev.java.net//downloads/v2-b58g.html with wget or FTP it onto both glassfish1 and glassfish2.
If you don't have Sun's Java JDK 5 or 6 installed on your machines, you'll need that first. If you're running Fedora, you can find a guide in my post 'Project, Part 1: Fedora + Sun Java' for installing Sun's Java JDK 1.5 build 13 on Fedora 7.
Time to setup glassfish1:
- Copy the installer jar file to /opt
cp <glassfish-installer>.jar /opt- Unpack the jar
java -Xmx256m -jar <glassfish-installer>.jar- Add the execute permission to the ant stuff
chmod -R +x glassfish/lib/ant/bin- Setup the cluster (this will create the DAS)
glassfish/lib/ant/bin/ant -f setup-cluster.xml- Add the glassfish bin directory to the path so we can call
asadminfrom anywhere emacs /etc/profile- In Fedora, there is a nice function
pathmunge, already in/etc/profile, which will allow you to add directories to the path without accidentally creating duplicates, so add the following line beforePATHis exported: pathmunge /opt/glassfish/bin- Start the default domain (domain1) with:
asadmin start-domain- Create the first node-agent
asadmin create-node-agent --host glassfish1 --port 4848 g1-a1- Create the cluster
asadmin create-cluster --host glassfish1 --port 4848 cluster1- Create the first instance
asadmin create-instance --host glassfish1 --port 4848 --nodeagent g1-a1 --cluster cluster1 g1-i1- Start the node-agent
asadmin start-node-agent --syncinstances=true g1-a1- Note: the
syncinstancesargument will start the associated instances and clusters as well, so you'll want to remember this for later.
cp <glassfish-installer>.jar /optjava -Xmx256m -jar <glassfish-installer>.jarchmod -R +x glassfish/lib/ant/libglassfish/lib/ant/bin/ant -f setup-cluster.xml
Note: the above will create a DAS on glassfish2... which we don't want, so you can remove the DAS after the script finishes with:
rm -rf /opt/glassfish/domains/domain1
If you want, you can avoid creating the DAS on glassfish2 in the first place by using the following command instead of the one above (#4):
glassfish/lib/ant/bin/ant -f setup-cluster.xml \
create-node-agent --Ddas.host=glassfish1
That will create a node-agent with the default name "na". If you want to specify the name of the node-agent, you'll need to edit setup-cluster.xml before running the above command. Find the property "nodeagent.name" and change the value to whatever name you want:
<property name="nodeagent.name" value="my-nodeagent-name" />
Either way, runningsetup-cluster.xml, which creates the DAS, then removing the DAS and creating a node agent will provide the same result as runningsetup-cluster.xmlwith the option to only create the node-agent.- Add
/opt/glassfish/binto thePATHas on glassfish1 - Create the second node-agent (If you didn't in step 4)
asadmin create-node-agent --host glassfish1 --port 4848 g2-a1- Create a new instance
asadmin create-instance --host glassfish1 --port 4848 --nodeagent g2-a1 --cluster cluster1 g2-i1- Start the second node agent
asadmin start-node-agent --syncinstances=true g2-a1
That's it! Well... sort of, there are a few things to note:
- Make sure that the firewall/SELinux/iptables rules are set to allow ports that are needed by Glassfish. These are, at the minimum:
- 4848 (admin HTTP)
- 8080 (HTTP)
- 8181 (HTTPS)
- 8686 (RMI)
- 3700 (ORB)
- 7676 (IMQ)
and possible others if those are already in use. If your node-agents are having trouble communicating, try disabling the firewall & SELinux, and set iptables to accept all incoming connections. DO NOT DO THIS AS A LONG TERM SOLUTION. IT IS ONLY MEANT TO RULE OUT PORT COMMUNICATIONS AS A PROBLEM. Depending on your needs, you may be altering the port configurations anyway. I decided to implement a white-listing policy, where I deny all incoming connections except the following:- On glassfish1:
- connections on port 8080 (for HTTP) from any IP
- connections on port 8181 (HTTPS) from any IP
- connections on port 4848 (HTTP admin GUI) from only my IP
- connections on any port from the IP of glassfish2
- On glassfish2:
- connections on any port from the IP of glassfish1
Thus, my servers are free to communicate with each other on any port they desire, but outside users may only connect to glassfish1 on 8080 and 8181, and only I can connect to glassfish1 on 4848. If you're messing with iptables, and you're not too familiar with *nix environments, you should probably have a *nix sys-admin check out your setup before it goes into production to make sure you haven't inadvertently created any security holes. - If you're having trouble starting your instances, especially g2-i1 on glassfish2 you might have to edit your
/etc/hostsfile... I did. This is something that you should check if the following shows up in yourserver.log:
[#|2007-11-05T12:19:03.832-0500|INFO|sun-appserver9.1|javax.ee.enterprise.system.nodeagent|_ThreadID=10;_ThreadName=main;|NAGT
0038:Executing Synchronization for node-agent With DAS|#]
[#|2007-11-05T12:19:12.920-0500|INFO|sun-appserver9.1|javax.ee.enterprise.system.tools.synchronization|_ThreadID=10;_ThreadNam
e=main;|SYNC001: Unable to communicate with Domain Administration Server. Skipping synchronization.|#]
[#|2007-11-05T12:19:12.922-0500|SEVERE|sun-appserver9.1|javax.ee.enterprise.system.nodeagent|_ThreadID=10;_ThreadName=main;|NA
GT0035:The NodeAgent failed to complete the intial synchronization with the DAS. Please make sure the DAS is running and is a
ccessible from the NodeAgents server|#]
[#|2007-11-05T12:19:14.925-0500|WARNING|sun-appserver9.1|javax.ee.enterprise.system.nodeagent|_ThreadID=10;_ThreadName=main;|N
AGT0013:Stopping Node Agent...|#]
Or, if the following shows up in your instanceserver.log:
[#|2007-11-07T02:25:31.352-0500|WARNING|sun-appserver9.1|javax.jms|_ThreadID=10;_ThreadName=main;_RequestID=efb5ac8e-778b-412b-ae9e-3af1e95a8ee2;|[C4003]: Error occurred on connection creation [localhost:37676]. - cause: java.net.ConnectException: Connection refused|#]
[#|2007-11-07T02:25:31.363-0500|WARNING|sun-appserver9.1|javax.enterprise.system.stream.err|_ThreadID=10;_ThreadName=main;_RequestID=efb5ac8e-778b-412b-ae9e-3af1e95a8ee2;|java.lang.RuntimeException: MQJMSRA_LB4001: start:Aborted:Unable to ping Broker within 60000 millis (startTimeOut)
at com.sun.messaging.jms.ra.LocalBrokerRunner.start(LocalBrokerRunner.java:366)
at com.sun.messaging.jms.ra.ResourceAdapter.start(ResourceAdapter.java:447)
at com.sun.enterprise.connectors.ActiveInboundResourceAdapter$1.run(ActiveInboundResourceAdapter.java:135)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.enterprise.connectors.ActiveInboundResourceAdapter.(ActiveInboundResourceAdapter.java:131)
at com.sun.enterprise.connectors.system.ActiveJmsResourceAdapter.(ActiveJmsResourceAdapter.java:247)
at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:107)
at com.sun.enterprise.connectors.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:300)
at com.sun.enterprise.connectors.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:445)
at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:224)
at com.sun.enterprise.jms.JmsProviderLifecycle.onStartup(JmsProviderLifecycle.java:428)
at com.sun.enterprise.server.ApplicationServer.onStartup(ApplicationServer.java:442)
at com.sun.enterprise.server.ondemand.OnDemandServer.onStartup(OnDemandServer.java:120)
at com.sun.enterprise.server.PEMain.run(PEMain.java:411)
at com.sun.enterprise.server.PEMain.main(PEMain.java:338)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.sun.enterprise.server.PELaunch.main(PELaunch.java:412)
|#]
What's happening here is that the node-agent is not starting because the instance is failing due to an MQ startup problem As it turns out, the MQ needs the hostname to point to an absolute address, not 127.0.0.1 or localhost. If you edit your/etc/hostsfile on glassfish1 to add:
xxx.xxx.xxx.xxx glassfish1
And on glassfish2 to add:
xxx.xxx.xxx.xxx glassfish2
then the problem should go away. Shalini, was kind enough to point that out to me and he has a blog post here that also mentions the problem. My original guide for doing this also came from Shalini's blog entry on setting up a 2 machine glassfish cluster using CLI.
