by René van Wijk
Simplifying the life-cycle management of a Java EE environment
February 2014
When we set-up a Java EE environment, we need an application server, such as Oracle WebLogic Server, that provides an easy way to set up a high-availability environment by configuring a cluster of servers across multiple machines. In such an environment, we also have to think about life-cycle management: How are we going to start and stop all the Managed Servers? How can we bring down Managed Servers on a machine that must go down for maintenance? What do we do when the Admin Server is not available? How can we recover from a machine crash without too much hassle?
In this article, we will investigate these questions and develop scripts—using the WebLogic Scripting Tool (WLST) and Linux Bash—that make the life-cycle management of a complex Java EE environment less of a burden. First, we will look at the basic scripts provided by a WebLogic configuration, so we get an idea of how WebLogic Servers are started and how Java Virtual Machine (JVM) parameters are set. Next, we will look at the role of the Node Manager and how to start and stop the Admin Server. We'll then discuss how Managed Servers can be stopped and started (in case the Admin Server is not available, or when a machine needs to go down for maintenance) and set up crash recovery. We will conclude with a summary of best practices.
Here are the various components in a WebLogic Server environment:
[For more information see: Understanding Oracle WebLogic Server: WebLogic Server Domains]
In addition to the Administration Server and Managed Servers, a domain also contains the resources and services that Managed Servers and deployed applications require. Managed Servers can use the following resource:
The Node Manager is a WebLogic Server utility that enables us to start, shut down, and restart Administration Server and Managed Server instances from a remote location. Detailed information on how the Node Manager works in a WebLogic environment is documented here.
In the WLST scripts presented below, we will use the Node Manager for the WebLogic Server lifecycle. We can use WLST to connect to a running Administration Server and manage the configuration of an active WebLogic domain, or view performance data about resources in the domain. WLST online is a Java Management Extensions (JMX) client. It interacts with a server's in-memory collection of managed beans (MBeans), which are Java objects that provide a management interface for an underlying resource. All WebLogic Server MBeans can be organized into one of the following general types, based on whether the MBean monitors or configures servers and resources:
In particular, to control the WebLogic Server lifecycle, we will use the ServerLifeCycleRuntimeMBean
(which provides methods that transition servers from one state to another) and the ServerRuntimeMBean
(which provides methods for retrieving run-time information about a server instance and for transitioning a server from one state to another). By using these MBeans, we can create generic scripts that can be used in all environments. Detailed information on how WLST (and the Node Manager) manage the server lifecycle is documented here.
Next to WLST, WebLogic Server provides an Administration Console that is deployed on the Administration Server. The Administration Console provides a graphical interface that interacts with WebLogic Server MBeans, allowing us to:
JMSServerRuntimeMBean
JMSServerMBean
Now that we have a basic understanding of how the WebLogic Server lifecycle works, we will see how out-of-the-box scripts set the parameters needed to actually create a WebLogic run-time – in other words, to start (or stop) a JVM that has as its main class weblogic.Server
. In order to run this class we need to tell the JVM which classes (CLASSPATH) to load and which native libraries (PATH) to use. Because these variables are set by the out-of-the-box scripts, no changes (usually) need to be made on this level. We will, however, usually change the JVM parameters (such as memory and the garbage collection scheme). Next, we continue with the set up of the Node Manager, and see how to create a Node Manager service. Subsequently, we will present the scripts for the Administration Server, followed by the scripts for the Managed Servers.
When we have installed WebLogic and configured a WebLogic domain, we get the following directory structure:
${DOMAIN_HOME}
/bin
setDomainEnv.sh (sets some java options and memory
parameters, calls ${WEBLOGIC_HOME}/common/bin/commEnv.sh and
${DOMAIN_HOME}/bin/setUserOverrides.sh)
setUserOverrides.sh
startManagedWebLogic.sh
startWebLogic.sh (calls setDomainEnv.sh)
startWebLogic.sh (calls /bin/startWebLogic.sh) ${WEBLOGIC_HOME}
/common/bin
commEnv.sh (calls ${FUSION_MIDDLEWARE_HOME}/common/bin/commEnv.sh)
${FUSION_MIDDLEWARE_HOME}
/common/bin
commEnv.sh (sets among others the ${LD_LIBRARY_PATH} and
${CLASSPATH} variables that are used in setDomainEnv.sh)
To start the Admin Server, we run the script startWebLogic.sh
, which starts the server by using the following line:
${JAVA_HOME}/bin/java ${JAVA_VM} ${MEM_ARGS} -
Dweblogic.Name=${SERVER_NAME} -
Djava.security.policy=${WLS_POLICY_FILE} ${JAVA_OPTIONS}
${PROXY_SETTINGS} ${SERVER_CLASS}
When looking at the scripts, we see that the memory parameters are set in the setDomainEnv.sh script
. We can provide our changes in a file called setUserOverrides.sh
. We can override memory parameters by using the ${USER_MEM_ARGS}
variable — for example:
#!/bin/sh
ADMIN_SERVER_MEM_ARGS="-Xms'${ADMIN_SERVER_HEAP_SIZE}' -
Xmx'${ADMIN_SERVER_HEAP_SIZE}' -
XX:PermSize='${ADMIN_SERVER_PERM_SIZE}' -
XX:MaxPermSize='${ADMIN_SERVER_PERM_SIZE}'"
SERVER_MEM_ARGS="-Xms'${MANAGED_SERVER_HEAP_SIZE}' -
Xmx'${MANAGED_SERVER_HEAP_SIZE}' -
XX:PermSize='${MANAGED_SERVER_PERM_SIZE}' -
XX:MaxPermSize='${MANAGED_SERVER_PERM_SIZE}'"
COHERENCE_SERVER_MEM_ARGS="-Xms'${COHERENCE_SERVER_HEAP_SIZE}' -
Xmx'${COHERENCE_SERVER_HEAP_SIZE}' -
XX:PermSize='${COHERENCE_SERVER_PERM_SIZE}' -
XX:MaxPermSize='${COHERENCE_SERVER_PERM_SIZE}'"
MONITORING_ARGS="-XX:+UnlockCommercialFeatures -
XX:+FlightRecorder"
COHERENCE_MONITORING_ARGS="-Dtangosol.coherence.management=all -
Dtangosol.coherence.management.remote=true"
GARBAGE_COLLECTOR_ARGS="-XX:NewRatio=3 -XX:SurvivorRatio=128 -
XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -
XX:GCTimeRatio=19 -XX:+UseParallelOldGC
-XX:+UseTLAB"
LARGE_PAGES_ARGS="-XX:LargePageSizeInBytes=2048k
-XX:+UseLargePages"
if [ "${ADMIN_URL}" = "" ] ; then
USER_MEM_ARGS="${ADMIN_SERVER_MEM_ARGS} ${GARBAGE_COLLECTOR_ARGS}"
else
case ${SERVER_NAME} in
server_*)
USER_MEM_ARGS="${SERVER_MEM_ARGS} ${GARBAGE_COLLECTOR_ARGS}
${MONITORING_ARGS}"
;;
coherence_server_1)
USER_MEM_ARGS="${COHERENCE_SERVER_MEM_ARGS}
${GARBAGE_COLLECTOR_ARGS} ${COHERENCE_MONITORING_ARGS}"
;;
coherence_server_*)
USER_MEM_ARGS="${COHERENCE_SERVER_MEM_ARGS}
${GARBAGE_COLLECTOR_ARGS}"
;;
esac fi export USER_MEM_ARGS
#if [ "${WEBLOGIC_EXTENSION_DIRS}" != "" ] ; then
# WEBLOGIC_EXTENSION_DIRS="${WEBLOGIC_EXTENSION_DIRS}
${CLASSPATHSEP}${DOMAIN_HOME}/lib"
#else
# WEBLOGIC_EXTENSION_DIRS="${DOMAIN_HOME}/lib"
#fi
#export WEBLOGIC_EXTENSION_DIRS'
As mentioned, to start the Admin Server, we can use ${DOMAIN_HOME}/startWebLogic.sh
. To start a Managed Server, we can use ${DOMAIN_HOME}/bin startManagedWebLogic.sh ${MANAGED_SERVER_NAME} ${ADMIN_URL}
(Note that the ${ADMIN_URL}
variable is already set in the script. If you start a Managed Server without the Admin Server being available, you'll see warnings in the logging:
[weblogic@machine1 bin]$ ./startManagedWebLogic.sh coherence_server_1
...
starting weblogic with Java version:
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
Starting WLS with line:
/u01/app/oracle/weblogic12.1.2/jdk1.7.0_25/bin/java -server -
Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m -
XX:NewRatio=3 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -
XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:GCTimeRatio=19 -
XX:+UseParallelOldGC -XX:+UseTLAB
-Dtangosol.coherence.management=all
-Dtangosol.coherence.management.remote=true
-Dweblogic.Name=coherence_server_1
-Djava.security.policy=/u01/app/oracle/weblogic12.1.2/installation/
wlserver/server/lib/weblogic.policy
-Dweblogic.ProductionModeEnabled=true
-Dweblogic.security.SSL.trustedCAKeyStore=/u01/app/oracle/weblogic12.1.2/installation/
wlserver/server/lib/cacerts -Xverify:none
-Djava.endorsed.dirs=/u01/app/oracle/weblogic12.1.2/jdk1.7.0_25/jre/lib/endorsed:/ u01/app/oracle/weblogic12.1.2/installation/wlserver/../oracle_common/modules/
endorsed -da
-Dwls.home=/u01/app/oracle/weblogic12.1.2/installation/wlserver/server
-Dweblogic.home=/u01/app/oracle/weblogic12.1.2/installation/wlserver/server
-Dweblogic.management.server=http://machine1.com:7001
weblogic.Server
...
<Aug 26, 2013 10:16:55 AM CEST> <Info> <Security> <BEA-090065>
<Getting boot identity from user.>
...
<Aug 26, 2013 10:17:09 AM CEST> <Info> <Management> <BEA-141107>
<Version: WebLogic Server 12.1.2.0.0 Fri Jun 7 15:16:15 PDT
2013 1530982 WLS_12.1.2.0.0_GENERIC_130607.1100>
<Aug 26, 2013 10:17:21 AM CEST> <Alert> <Management> <BEA-141151>
<The Administration Server could not be reached at http://machine1.com:7001.>
<Aug 26, 2013 10:17:21 AM CEST> <Info> <Configuration Management>
<BEA-150018> <This server is being started in Managed Server independence mode
in the absence of the Administration Server.>
...
<Aug 26, 2013 10:17:34 AM CEST> <Warning> <JTA> <BEA-110503>
<The migrator (the Administration Server for manual JTA migration policy or the
Singleton Master for automatic JTA migration policy) is not available. Will skip JTA
TRS failback because isStrictOwnershipCheck is [false]. This may lead to potencial
TLOG corruption if the TRS of coherence_server_1 has been migrated to a backup
server and the backup server is accessing the TLOG of coherence_server_1. More
safety can be achieved by setting isStrictOwnershipCheck to [true].>
...
<Aug 26, 2013 10:18:20 AM CEST> <Warning> <JMX> <BEA-149510>
<Unable to establish JMX Connectivity with the Administration Server AdminServer
at <JMXServiceURL:null>.>
<Aug 26, 2013 10:18:20 AM CEST> <Notice> <WebLogicServer>
<BEA-000365> <Server state changed to RUNNING.>
<Aug 26, 2013 10:18:20 AM CEST> <Notice> <WebLogicServer>
<BEA-000360> <The server started in RUNNING mode.>
<Aug 26, 2013 10:18:24 AM CEST> <Warning> <Log Management>
<BEA-170011> <The LogBroadcaster on this server failed to broadcast
log messages to the Administration Server. The Administration Server may not
be running. Message broadcasts to the Administration Server will be disabled.>
In this case, the Managed Server will be running in Managed Server Independence Mode.
When configuring a migration policy for singleton services, which is based on consensus-based leasing, the Managed Server can be started only through the Node Manager.
The Node Manager Overview provides start scripts for the Node Manager:
${DOMAIN_HOME}
/bin
startNodeManager.sh (sets ${NODEMGR_HOME} and calls
${WEBLOGIC_HOME}/server/bin/startNodeManager.sh) ${WEBLOGIC_HOME}
/server/bin
startNodeManager.sh (calls calls
${FUSION_MIDDLEWARE_HOME}/common/bin/commEnv.sh)
These scripts boil down to the following starting line:
"${JAVA_HOME}/bin/java" ${JAVA_VM} ${MEM_ARGS} ${JAVA_OPTIONS} - Djava.security.policy="${WL_HOME}/server/lib/weblogic.policy" -
Dweblogic.nodemanager.JavaHome="${JAVA_HOME}" -
DListenAddress="${LISTEN_ADDRESS}" -
DListenPort="${LISTEN_PORT}" weblogic.NodeManager -v
When using the WebLogic Scripting Tool, start the Node Manager by using the following:
import socket;
node_manager_listen_address = socket.gethostname();
print 'CREATE PATHS'; domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=domain_home + '/nodemanager';
print 'STARTING NODE MANAGER';
startNodeManager(verbose='true',
NodeManagerHome=node_manager_home,
ListenPort=node_manager_listen_port,
ListenAddress=node_manager_listen_address);
To run this script, use:
#!/bin/sh
SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)
. ${SCRIPT_PATH}/../SetEnvironmentVariables.sh
${WEBLOGIC_HOME}/common/bin/wlst.sh -loadProperties
${SCRIPT_PATH}/../environment.properties
${SCRIPT_PATH}/startNodeManager.py
The environment variables used are set by a script called SetEnvironmentVariables.sh:
#!/bin/sh
# Name of the domain
DOMAIN_NAME="base_domain"
export DOMAIN_NAME
# Directory where the software to be installed is located SOFTWARE_DIRECTORY="/u01/software/weblogic/12.1.2"
export SOFTWARE_DIRECTORY
# The scripts create files that are placed in this directory
TEMPORARY_DIRECTORY="${SOFTWARE_DIRECTORY}/files"
export TEMPORARY_DIRECTORY
# Name of JVM file JVM_FILE_NAME="jdk-7u25-linux-x64.tar.gz"
export JVM_FILE_NAME
# Name of the WebLogic file
WEBLOGIC_FILE_NAME="wls_121200.jar"
export WEBLOGIC_FILE_NAME
# Base directory
BASE_DIRECTORY="/u01/app/oracle"
export BASE_DIRECTORY
# Directory that will used for the installation and configuration
RUNTIME_HOME="${BASE_DIRECTORY}/weblogic12.1.2"
export RUNTIME_HOME
# Directory where the JVM will be installed
JAVA_HOME="${RUNTIME_HOME}/jdk1.7.0_25" export JAVA_HOME
# Directory that will be used as the middleware home (holds software binaries)
MIDDLEWARE_HOME="${RUNTIME_HOME}/installation"
export MIDDLEWARE_HOME
# Depending on the WebLogic version to be installed,
edit the wlserver_major.minor version
WEBLOGIC_HOME="${MIDDLEWARE_HOME}/wlserver"
export WEBLOGIC_HOME
# Depending on the Coherence version to be installed,
edit the coherence_major.minor version
COHERENCE_HOME="${MIDDLEWARE_HOME}/coherence"
export COHERENCE_HOME
# Directory where the fusion middleware software will be installed
FUSION_MIDDLEWARE_HOME="${MIDDLEWARE_HOME}/oracle_common"
export FUSION_MIDDLEWARE_HOME
# Location of the Oracle inventory ORACLE_INVENTORY_HOME="${BASE_DIRECTORY}/oraInventory"
export ORACLE_INVENTORY_HOME
# Group under which the software needs to be installed ORACLE_INSTALL_GROUP="javainstall" export ORACLE_INSTALL_GROUP
# Directory where the configuration will be placed
CONFIGURATION_HOME="${RUNTIME_HOME}/configuration"
export CONFIGURATION_HOME
This corresponds with the directory set-up mentioned earlier. When using the WebLogic Scripting Tool, user names, passwords, etc., are set by using the following properties (environment.properties)
file:
node_manager_username=nodemanager
node_manager_password=magic12c
node_manager_listen_port=5556
node_manager_mode=plain
admin_server_name=AdminServer
admin_username=weblogic
admin_password=magic12c
admin_server_listen_port=7001
Below is an example of how to encrypt the passwords. If we are going to use the script in another environment, only the filesSetEnvironmentVariables.sh
and environment.properties
need to be changed.
In general, we should start the Node Manager when the machine boots. In this case, we need to know where to put the custom commands that will be called when the system boots. Linux has a /etc/rc.d/rc.local
file in which custom commands can be put.
Let us do it in the recommended script-based way. Unix-based systems specify so-called run levels; for each run level, scripts can be defined that start a certain service. These scripts are located in the /etc/rc.d/init.d
directory. Services can be started when the system boots or be stopped on system shutdown. The different run levels are specified by a specific directory in the /etc/rc.d directory:
The boot sequence is as follows: in the /etc/inittab
file, the starting run level is defined, the script /etc/rc.d/rc.sysinit
is called, and /etc/rc.d/rc
is run. The rc
script looks in /etc/rc.d/rc<start-runlevel>.d
to execute the K**<script-name>
scripts with the stop option. After this, the
S**<script-name> scripts are executed with the start option. (Note that scripts are started in numerical order, i.e., the S10network
script is executed before the S80sendmail
script.)
To create a Node Manager "service," use the following script:
#!/bin/sh
#
# chkconfig: - 91 35
#
# description: Node Manager controls the WebLogic Server runtime
lifecycle
# processname: nodemanager
#
# Source function library.
. /etc/rc.d/init.d/functions
RETVAL=0 SERVICE="nodemanager"
USER="weblogic"
SCRIPTS_LOCATION="/u01/software/weblogic/12.1.2/scripts
/lifecycle"
LOCK_FILE="/var/lock/subsys/${SERVICE}"
start()
{
echo "Starting Node Manager"
su - ${USER} -c "${SCRIPTS_LOCATION}/NodeManagerStartService.sh" >
/dev/null 2>&1
RETVAL=$?
[ $RETVAL -eq 0 ] && success || failure
echo
[ $RETVAL -eq 0 ] && touch ${LOCK_FILE}
return $RETVAL
}
stop()
{
echo "Stopping Node Manager"
su - ${USER} -c "${SCRIPTS_LOCATION}/NodeManagerStopService.sh" >
/dev/null 2>&1
RETVAL=$?
[ $RETVAL -eq 0 ] && success || failure
echo
[ $RETVAL -eq 0 ] && rm -r ${LOCK_FILE}
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
Place this script in the /etc/rc.d/init.d
directory. Update the run level information for system services by using the chkconfig
command (e.g., chkconfig --add nodemanager and chkconfig nodemanager on
). To test the set-up, shut the system down and start it again. To check if the Node Manager is running, use eitherps -ef|grep java
or netstat -anp|grep :5556
(which assumes the Node Manager is listening on port 5556).
Also consider setting theCrashRecoveryEnabled
property to "true" (allowing the Node Manager to restart servers after a system crash), because the property is not enabled by default. After the system is restarted, the Node Manager checks each managed domain specified in the nodemanager.domains
file to determine if any server instances were not cleanly shut down. This is determined by the presence of any lock files, which are created by the Node Manager when a WebLogic Server process is created. This lock file contains the process identifier for the WebLogic Server start-up script. If the lock file exists, but the process ID is not running, the Node Manager will attempt to automatically restart the server. If the process is running, the Node Manager performs an additional check, accessing the management servlet running in the process to verify that the process corresponding to the process ID is a WebLogic Server instance. To test the process, start all the servers and then reboot the host. When the server comes back up again, the state files (${DOMAIN_HOME}/server/${SERVER_NAME}/data/nodemanager/${SERVER_NAME}.state)
contain a FORCE_SHUTTING_DOWN entry. In this case, the server is in an incompatible state for the server to be started by either the console or the WebLogic Scripting Tool. With CrashRecoveryEnabled set to true, the Node Manager will detect the lock file and will automatically start the servers; we can also edit the state files by hand and set the state to SHUTDOWN, which should be nice when running in an environment with many servers.
...
<Aug 26, 2013 11:24:08 AM CEST> <INFO> <base_domain>
<coherence_server_1>
<The server 'coherence_server_1' is running now.>
<Aug 26, 2013 11:24:15 AM CEST> <INFO> <base_domain>
<server_machine1.com_9002>
<The server 'server_machine1.com_9002' is running now.>
<Aug 26, 2013 11:24:16 AM CEST> <INFO> <base_domain>
<server_machine1.com_9001>
<The server 'server_machine1.com_9001' is running now.>
# reboot
<Aug 26, 2013 11:30:16 AM CEST> <INFO> <Loading domains file:
/u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain/nodemanager/
nodemanager.domains>
<Aug 26, 2013 11:30:17 AM CEST> <INFO> <Loaded NodeManager
configuration properties from '/u01/app/oracle/weblogic12.1.2/configuration/domains/
base_domain/nodemanager/nodemanager.properties'>
<Aug 26, 2013 11:30:17 AM CEST> <INFO>
<WebLogic Server 12.1.2.0.0 Fri Jun 7 15:16:15 PDT 2013 1530982
WLS_12.1.2.0.0_GENERIC_130607.1100>
...
<Aug 26, 2013 11:30:17 AM CEST> <INFO> <base_domain>
<AdminServer>
<Automatically restarting server process as part of crash recovery>
...
<Aug 26, 2013 11:30:18 AM CEST> <INFO> <base_domain>
<AdminServer> <Starting WebLogic server with command line:
/u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain/bin/
startWebLogic.sh >
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<AdminServer> <The server 'AdminServer' is running now.>
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<coherence_server_1> <Automatically restarting server process
as part of crash recovery>
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<coherence_server_1> <Starting WebLogic server with command line:
/u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain/bin/
startWebLogic.sh >
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<server_machine1.com_9002> <Automatically restarting server
process as part of crash recovery>
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<server_machine1.com_9002> <Starting WebLogic server with command line:
/u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain/bin/
startWebLogic.sh >
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<server_machine1.com_9001> <Automatically restarting server
process as part of crash recovery>
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO> <base_domain>
<server_machine1.com_9001> <Starting WebLogic server with command line:
/u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain/bin/
startWebLogic.sh >
...
<Aug 26, 2013 11:31:05 AM CEST> <INFO>
<Plain socket listener started on port 5556, host machine1.com>
<Aug 26, 2013 11:31:26 AM CEST> <INFO> <base_domain>
<coherence_server_1>
<The server 'coherence_server_1' is running now.>
<Aug 26, 2013 11:31:30 AM CEST> <INFO> <base_domain>
<server_machine1.com_9001>
<The server 'server_machine1.com_9001' is running now.>
<Aug 26, 2013 11:31:36 AM CEST> <INFO> <base_domain>
<server_machine1.com_9002>
<The server 'server_machine1.com_9002' is running now.>
...
To stop the Node Manager, we can use:
import socket;
node_manager_listen_address = socket.gethostname();
print 'CREATE PATHS';
domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/'
+ domain_name; node_manager_home=domain_home + '/nodemanager';
print 'STOPPING NODE MANAGER';
nmConnect(node_manager_username, node_manager_password,
node_manager_listen_address, node_manager_listen_port,
domain_name, domain_home, node_manager_mode);
stopNodeManager();
With nmConnect
, we have two options to provide a username and password – either through properties (as with the example above) or by using a user config and key file. In the latter case, we have to use storeUserConfig
. For example:
import socket;
node_manager_listen_address = socket.gethostname();
admin_server_listen_address = node_manager_listen_address;
print 'CREATE PATHS'; domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=configuration_home + '/nodemanagers/' + domain_name;
print 'CONNECT TO NODE MANAGER';
nmConnect(node_manager_username, node_manager_password, node_manager_listen_address,
node_manager_listen_port, domain_name, domain_home, node_manager_mode);
print 'CREATE NODE MANAGER USER CONFIG FILES';
storeUserConfig(domain_home +'/node_manager_config_file.properties', domain_home +
'/node_manager_key_file.properties', 'true');
print 'DISCONNECT FROM NODE MANAGER';
nmDisconnect();
print 'CONNECT TO ADMIN SERVER';
admin_server_url = 't3://' + admin_server_listen_address + ':'
+ admin_server_listen_port;
connect(admin_username, admin_password, admin_server_url);
print 'CREATE ADMIN SERVER USER CONFIG FILES';
storeUserConfig(domain_home +'/admin_server_config_file.properties',
domain_home + '/admin_server_key_file.properties', 'false');
print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();
When the script is run, the following output is observed:
[weblogic@machine1 basicconfiguration]$ ./StoreUserConfigService.sh
Initializing WebLogic Scripting Tool (WLST)
...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
CREATE PATHS CONNECT TO NODE MANAGER
Connecting to Node Manager
...
Successfully Connected to Node Manager.
CREATE NODE MANAGER USER CONFIG FILES
Currently connected to Node Manager to monitor the domain base_domain.
Creating the key file can reduce the security of your system if it is
not kept in a secured location after it is created. Do you want to create
the key file? y or ny The username and password that were used for this WebLogic NodeManager
connection are stored in /u01/app/oracle/weblogic12.1.2/configuration/domains
/base_domain/node_manager_config_file.properties and
/u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain
/node_manager_key_file.properties.
DISCONNECT FROM NODE MANAGER
Successfully disconnected from Node Manager.
CONNECT TO ADMIN SERVER
Connecting to t3://machine1.com:7001 with userid weblogic ...
Successfully connected to Admin Server "AdminServer" that belongs to
domain "base_domain".
Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.
CREATE ADMIN SERVER USER CONFIG FILES
Creating the key file can reduce the security of your system if it is not
kept in a secured location after it is created. Do you want to create the
key file? y or ny
The username and password that were used for this WebLogic Server connection
are stored in /u01/app/oracle/weblogic12.1.2/configuration/domains/base_domain
/admin_server_config_file.properties and /u01/app/oracle/weblogic12.1.2
/configuration/domains/base_domain
/admin_server_key_file.properties.
DISCONNECT FROM THE ADMIN SERVER
Disconnected from weblogic server: AdminServer
We can use the stored config files as follows:
import socket;
node_manager_listen_address = socket.gethostname();
print 'CREATE PATHS';
domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=domain_home + '/nodemanager';
print 'STOPPING NODE MANAGER';
#nmConnect(node_manager_username, node_manager_password,
node_manager_listen_address, node_manager_listen_port, domain_name,
domain_home, node_manager_mode);
nmConnect(userConfigFile=domain_home +'/node_manager_config_file.properties',
userKeyFile=domain_home + '/node_manager_key_file.properties',
host=node_manager_listen_address, port=node_manager_listen_port,
domainName=domain_name, domainDir=domain_home, nmType=node_manager_mode);
stopNodeManager();
When we have the Node Manager running, we can start the Admin Server.
To start the Admin Server through the Node Manager, use nmStart
. For example:
import socket;
node_manager_listen_address = socket.gethostname();
print 'CREATE PATHS';
domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=domain_home + '/nodemanager';
print 'CONNECT TO NODE MANAGER';
nmConnect(node_manager_username,
node_manager_password, node_manager_listen_address,
node_manager_listen_port, domain_name, domain_home, node_manager_mode);
print 'START ADMIN SERVER';
nmStart(admin_server_name);
print 'DISCONNECT FROM NODE MANAGER';
nmDisconnect();
Note:boot.properties
(in ${DOMAIN_HOME}/servers/${ADMIN_SERVER_NAME}/security)
must exist in order to start a server with nmStart
. To stop the Admin Server, we can use:
import socket;
node_manager_listen_address = socket.gethostname();
admin_server_listen_address = node_manager_listen_address;
print 'CREATE PATHS';
domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=domain_home + '/nodemanager';
print 'CONNECT TO ADMIN SERVER';
admin_server_url = 't3://' + admin_server_listen_address + ':'
+ admin_server_listen_port;
connect(admin_username, admin_password, admin_server_url);
print 'CONNECT TO NODE MANAGER';
nmConnect(node_manager_username, node_manager_password, node_manager_listen_address,
node_manager_listen_port, domain_name, domain_home, node_manager_mode);
print 'STOPPING ADMIN SERVER';
shutdown(admin_server_name,'Server','true',1000,'true');
print 'DISCONNECT FROM NODE MANAGER';
nmDisconnect();
Although we could also have used nmKill
to stop the Admin Server, instead of shutdown, the shutdown command gives more fine-grained control when shutting down a server (such as setting a time-out when a server is shut down gracefully).
Typically, when a WebLogic Server instance is started, all services are started, including Enterprise JavaBeans (EJB), Java Message Service (JMS), Java EE Connector Architecture (JCA), clustering, deployment, management, and so forth. However, the WebLogic Server provides a startup option (-DserverType="wlx"
) that offers a lighter-weight run-time footprint by excluding a subset of these services from being started. This startup mode can result in quicker startup times for the WebLogic Server and a smaller resource footprint on the host machine. The set of services started in a WebLogic Server instance are determined by the Server Type startup command, which takes a server type option. There are two server type options:
wls
- All services are started (default)wlx
- All but the following services are started:
If a WebLogic Server instance does not require the use of these services, running the lighter-weight run time instead can provide performance efficiencies.
To stop and start a Managed Server within the domain, we are going to use the ServerLifeCycleRuntimeMBean
, which provides methods that transition servers from one state to another. This class is instantiated only on the Admin Server, and can be used to transition the states of Managed Servers (it cannot be used to start the Admin Server). When we want to use it to start Managed Servers, we must first set up a Node Manager on each managed server's host machine. To start Managed Servers, we can use:
import socket;
print 'CONNECT TO ADMIN SERVER';
admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':'
+ admin_server_listen_port;
connect(admin_username, admin_password, admin_server_url);
print 'STARTING SERVERS';
domainRuntime();
server_lifecycles = cmo.getServerLifeCycleRuntimes();
for server_lifecycle in server_lifecycles:
if (server_lifecycle.getState() == 'SHUTDOWN' and server_lifecycle.getName()
!= admin_server_name):
print 'START SERVER ' + server_lifecycle.getName();
task = server_lifecycle.start();
java.lang.Thread.sleep(1000);
print task.getStatus() + ', ' + server_lifecycle.getState();
else:
print 'SERVER ' + server_lifecycle.getName() + ' is in '
+ server_lifecycle.getState() + ' state and will not be started';
print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();
To stop Managed Servers, we can use:
import socket;
print 'CONNECT TO ADMIN SERVER';
admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':'
+ admin_server_listen_port;
connect(admin_username, admin_password, admin_server_url);
print 'STOPPING SERVERS'; domainRuntime();
server_lifecycles = cmo.getServerLifeCycleRuntimes();
for server_lifecycle in server_lifecycles:
if (server_lifecycle.getState() == 'RUNNING' and server_lifecycle.getName()
!= admin_server_name):
print 'STOP SERVER ' + server_lifecycle.getName();
task = server_lifecycle.shutdown(1000, java.lang.Boolean('true'));
java.lang.Thread.sleep(1000);
print task.getStatus() + ', ' + server_lifecycle.getState();
else:
print 'SERVER ' + server_lifecycle.getName() + ' is in ' +
server_lifecycle.getState() + ' state and will not be stopped';
print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();
With the stored user config files, we can also connect to the Admin Server using:
connect(userConfigFile=domain_home +'/admin_server_config_file.properties',
userKeyFile=domain_home + '/admin_server_key_file.properties',
url=admin_server_url);
The above scripts start and stop all Managed Servers in the domain. To stop only the servers on a certain host, we need information on what host the WebLogic instance is actually running. In this case, we can use the ServerRuntimeMBean,
which provides methods for retrieving run-time information about a server instance and for transitioning a server from one state to another. Use this to stop Managed Server instances locally:
import socket;
node_manager_listen_address=socket.gethostname();
node_manager_listen_ip_address=socket.gethostbyname(node_manager_listen_address);
print 'CREATE PATHS';
domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=configuration_home + '/nodemanagers/' + domain_name;
print 'CONNECT TO ADMIN SERVER';
command_output = os.popen('find ' + domain_home + ' -name startup.properties');
output = command_output.readline();
command_output.close();
loadProperties(output.rstrip());
admin_server_url = AdminURL.replace('http','t3');
connect(admin_username, admin_password, admin_server_url);
print 'CONNECT TO NODE MANAGER ON ' + node_manager_listen_address + ':'
+ repr(node_manager_listen_port);
nmConnect(node_manager_username, node_manager_password, node_manager_listen_address,
node_manager_listen_port, domain_name, domain_home, node_manager_mode);
domainRuntime();
cd('ServerRuntimes'); server_runtimes = ls(returnMap='true');
for server_runtime in server_runtimes:
cd(server_runtime);
if (cmo.getName() != admin_server_name):
host = cmo.getListenAddress().split('/');
if (node_manager_listen_address == host[0] or node_manager_listen_ip_address
== host[1]):
print 'STOP SERVER ' + cmo.getName();
shutdown(cmo.getName(),'Server','true',1000,'true');
else:
print 'SERVER ' + cmo.getName() + ' runs on a different host and will
not be stopped';
else:
print 'SERVER ' + cmo.getName() + ' is the Admin Server and will not be
stopped';
cd('..');
print 'DISCONNECT FROM NODE MANAGER ON ' + node_manager_listen_address + ':'
+ repr(node_manager_listen_port);
nmDisconnect();
print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();
Here, we retrieve the Admin Server URL by using the startup.properties
file (${DOMAIN_HOME}/servers/${SERVER_NAME}/data/nodemanager)
that is created when the server is started through the Node Manager for the first time. The startup.properties
contains an AdminURL
property that contains the URL of the Admin Server. When the script is run, the following output is observed:
[weblogic@machine2 lifecycle]$ ./LocalStopService.sh
Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
CREATE PATHS
CONNECT TO ADMIN SERVER
Connecting to t3://192.168.1.155:7001 with userid weblogic ...
Successfully connected to Admin Server "AdminServer" that belongs to domain "base_domain".
Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.
CONNECT TO NODE MANAGER ON machine2.com:'5556'
Connecting to Node Manager ...
Successfully Connected to Node Manager.
Location changed to domainRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help('domainRuntime')
dr-- AdminServer
dr-- coherence_server_1
dr-- coherence_server_2
dr-- server_machine1.com_9001
dr-- server_machine1.com_9002
dr-- server_machine2.com_9001
dr-- server_machine2.com_9002
SERVER AdminServer is the Admin Server and will not be stopped
SERVER coherence_server_1 runs on a different host and will not be stopped
STOP SERVER coherence_server_2
Shutting down the server coherence_server_2 with force=true while connected to AdminServer ...
SERVER server_machine1.com_9001 runs on a different host and will not be stopped
SERVER server_machine1.com_9002 runs on a different host and will not be stopped
STOP SERVER server_machine2.com_9001
Shutting down the server server_machine2.com_9001 with force=true while connected to
AdminServer ...
STOP SERVER server_machine2.com_9002
Shutting down the server server_machine2.com_9002 with force=true while connected to
AdminServer ...
DISCONNECT FROM NODE MANAGER ON machine2.com:'5556'
Successfully disconnected from Node Manager.
DISCONNECT FROM THE ADMIN SERVER
Disconnected from weblogic server: AdminServer
In the scripts presented above, we connect to Admin Server in order to retrieve run-time information. When the Admin Server is not available and we want to stop and start a managed server, we have to resort to nmKill
and nmStart,
respectively. To start a Managed Server in independence mode we can use:
nmConnect(node_manager_username, node_manager_password, node_manager_listen_address,
node_manager_listen_port, domain_name, domain_home, node_manager_mode);
nmStart(managed_server_name);
Here is an example:
wls:/offline> nmConnect(node_manager_username, node_manager_password,
node_manager_listen_address, node_manager_listen_port, domain_name, domain_home,
node_manager_mode);
Connecting to Node Manager ...
Successfully Connected to Node Manager.
wls:/nm/base_domain> nmStart('coherence_server_2');
Starting server coherence_server_2 ...
Successfully started server coherence_server_2 ...
To use nmStart
we need to obtain the server names. The ${DOMAIN_HOME}/servers
contains directories named after the servers; for example, in our case, we have:
${DOMAIN_HOME}
/servers
/AdminServer
/coherence_server_1
/domain_bak
/server_machine1.com_9001
/server_machine2.com_9002
Obtain the names of the directories by using the File API. To combine this with the WLST commands nmConnect
and nmStart (or nmKill),
create a script such as:
import socket;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
print 'CREATE PATHS';
domain_name=os.getenv('DOMAIN_NAME');
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');
domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=domain_home + '/nodemanager';
print 'OBTAIN SERVER NAMES';
defiles = java.io.File(domain_home + '/servers');
delist = java.util.Arrays.asList(defiles.list());
denames = java.util.ArrayList(delist);
print 'CONNECT TO NODE MANAGER';
node_manager_listen_address = socket.gethostname();
nmConnect(node_manager_username, node_manager_password, node_manager_listen_address,
node_manager_listen_port, domain_name, domain_home, node_manager_mode);
print 'STARTING SERVERS';
for dename in denames:
if (dename != admin_server_name and dename != 'domain_bak'):
nmStart(dename);
# nmKill(dename);
print 'DISCONNECT FROM NODE MANAGER';
nmDisconnect();
When this script is executed, the following output is observed:
# nmStart
[weblogic@machine1 lifecycle]$ ./tryout.sh
Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
CREATE PATHS
OBTAIN SERVER NAMES
CONNECT TO NODE MANAGER
Connecting to Node Manager ...
Successfully Connected to Node Manager.
STARTING SERVERS
Starting server server_machine1.com_9002 ...
Successfully started server server_machine1.com_9002 ...
Starting server server_machine1.com_9001 ...
Successfully started server server_machine1.com_9001 ...
Starting server coherence_server_1 ...
Successfully started server coherence_server_1 ...
DISCONNECT FROM NODE MANAGER
Successfully disconnected from Node Manager.
#nmKill
[weblogic@machine1 lifecycle]$ ./tryout.sh
Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
CREATE PATHS
OBTAIN SERVER NAMES
CONNECT TO NODE MANAGER
Connecting to Node Manager ...
Successfully Connected to Node Manager.
STARTING SERVERS
Killing server server_machine1.com_9002 ...
Successfully killed server server_machine1.com_9002
Killing server server_machine1.com_9001 ...
Successfully killed server server_machine1.com_9001
Killing server coherence_server_1 ...
Successfully killed server coherence_server_1
DISCONNECT FROM NODE MANAGER
Successfully disconnected from Node Manager.
Note the remark in the documentation: "boot.properties must exist in order to start a server with nmStart. If this is the first time you are starting a server or the first time you are using Node Manager, you must manually create it or run the nmGenBootStartupProps
command to generate boot.properties and startup.properties files for the server." For example:
wls:/base_domain/serverConfig> nmGenBootStartupProps('coherence_server_1');
Successfully generated boot.properties at
/u01/software/weblogic/12.1.2/scripts/servers/coherence_server_1/data/nodemanager/
boot.properties.
Successfully generated startup.properties at
/u01/software/weblogic/12.1.2/scripts/servers/coherence_server_1/data/nodemanager/
startup.properties.
The files are created in the directory where WLST was started (so the files still have to be copied to the ${DOMAIN_HOME}/servers/${SERVER_NAME}/data/nodemanager directory).
It's good practice to create a "service" for the Node Manager, such that it is available when the machine boots. Consider setting the CrashRecoveryEnabled
to "true," so there will be no trouble when the machine reboots. Also consider using plain (instead of ssl
) communication for the Node Manager (or, if you are in a really unsafe network, use ssl and create your own keystores). Set up a Node Manager per domain instead of per machine. Start the Admin Server through the Node Manager and the managed servers through the Admin Server. To ensure that the Node Manager properly restarts servers after a system crash, CrashRecoveryEnabled
must be enabled as well. In this case we do not need more in the boot sequence of our machine than the Node Manager.
[1] WebLogic Server Documentation
René van Wijk
Twitter Blog LinkedIn Facebook Oracle ACE Director
Oracle ACE Director René van Wijk works with numerous technologies, including Oracle Coherence, Oracle WebLogic, Hibernate, Java Virtual Machine, JBoss, and Spring. A graduate of the Delft University of Technology, René transfers his knowledge and experience regularly through training, publications and presentations at seminars and conferences.