| |||
|
简化 Java EE 环境的生命周期管理
2014 年 2 月
搭建 Java EE 环境时,我们需要一个应用服务器(如 Oracle WebLogic Server),这样可以通过配置跨多台计算机的服务器集群,轻松搭建高可用性环境。在这种环境中,我们还必须考虑生命周期管理:如何启动和停止所有受管服务器?如何停止必须停机维护的计算机上的受管服务器?管理服务器不可用时该怎么办?如何从容恢复崩溃的计算机?
本文将对研究这些问题,并使用 WebLogic Scripting Tool (WLST) 和 Linux Bash 开发可以简化复杂 Java EE 环境生命周期管理的脚本。首先,我们将看看 WebLogic 配置提供的基本脚本,了解如何启动 WebLogic Server 以及如何设置 Java 虚拟机 (JVM) 参数。接下来,我们将介绍 Node Manager 的作用以及如何启动和停止管理服务器。然后,我们将讨论如何停止和启动受管服务器(如果管理服务器不可用或计算机需要停机维护)以及设置崩溃恢复。最后将总结最佳实践。
下面是 WebLogic Server 环境中的各种组件:
[有关更多信息,请参见:了解 Oracle WebLogic Server:WebLogic Server 域]
除了管理服务器和受管服务器,域还包含受管服务器和部署的应用程序所需的资源和服务。受管服务器可以使用以下资源:
Node Manager 是一个 WebLogic Server 实用程序,可用于从远程位置启动、关闭以及重新启动管理服务器和受管服务器实例。此处记载了有关 Node Manager 在 WebLogic 环境中的工作方式的详细信息。
在以下展示的 WLST 脚本中,我们将使用 Node Manager 管理 WebLogic Server 生命周期。我们可以使用 WLST 连接到正在运行的管理服务器,管理活动的 WebLogic 域的配置,或者查看有关域中资源的性能数据。WLST Online 是一个 Java 管理扩展 (JMX) 客户端。它与服务器的内存中受管 bean(MBean,为底层资源提供管理界面的 Java 对象)集合交互。可以根据 MBean 是监视还是配置服务器和资源,将所有 WebLogic Server MBean 组织成以下通用类型之一:
特别是,为了控制 WebLogic Server 生命周期,我们将使用 ServerLifeCycleRuntimeMBean
(提供将服务器从一种状态转换到另一种状态的方法)和 ServerRuntimeMBean
(提供用于检索有关服务器实例的运行时信息和将服务器从一种状态转换到另一种状态的方法)。使用这些 MBean,我们可以创建所有环境均可以使用的通用脚本。此处记载了有关 WLST(和 Node Manager)如何管理服务器生命周期的详细信息。
继 WLST 之后,WebLogic Server 还提供了一个管理控制台,部署在管理服务器上。管理控制台提供了一个与 WebLogic Server MBean 交互的图形界面,在此界面上可以:
JMSServerRuntimeMBean
交互,查看来自 JMS 服务器的运行时信息JMSServerMBean
交互,配置环境(例如,配置 JMS 服务器)对 WebLogic Server 生命周期的工作方式有了基本了解之后,我们将看看现成脚本如何设置实际创建 WebLogic 运行时 — 换句话说,启动(或停止)拥有主类 weblogic.Server
的 JVM — 所需的参数。为了运行此类,我们需要告知 JVM 加载哪些类 (CLASSPATH) 和使用哪些原生库 (PATH)。因为这些变量由现成脚本设置,(通常)无需在此级别进行更改。不过,我们通常会更改 JVM 参数(例如内存和垃圾收集方案)。接下来,我们继续设置 Node Manager,并看看如何创建 Node Manager 服务。之后,我们将展示用于管理服务器的脚本,然后是用于受管服务器的脚本。
已经安装了 WebLogic 并配置了 WebLogic 域后,我们将得到以下目录结构:
${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)
要启动管理服务器,我们运行 startWebLogic.sh
脚本,它将使用以下代码行启动服务器:
${JAVA_HOME}/bin/java ${JAVA_VM} ${MEM_ARGS} - Dweblogic.Name=${SERVER_NAME} - Djava.security.policy=${WLS_POLICY_FILE} ${JAVA_OPTIONS} ${PROXY_SETTINGS} ${SERVER_CLASS}
查看脚本时,我们看到 setDomainEnv.sh
脚本中已经设置了内存参数。我们可以在 setUserOverrides.sh
文件中提供更改。可以使用 ${USER_MEM_ARGS}
变量覆盖内存参数 — 例如:
#!/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'
如上所述,要启动管理服务器,可以使用 ${DOMAIN_HOME}/startWebLogic.sh
。要启动受管服务器,可以使用 ${DOMAIN_HOME}/bin startManagedWebLogic.sh ${MANAGED_SERVER_NAME} ${ADMIN_URL}
(注,${ADMIN_URL}
变量已在脚本中设置)。如果在管理服务器不可用的情况下启动受管服务器,将在日志中看到以下警告:
[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 ......
在本例中,受管服务器将以受管服务器独立模式运行。
为基于以共识为基础的租赁的单一服务配置迁移策略时,只能通过 Node Manager 启动受管服务器。
Node Manager 概述提供了 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)
这些脚本的核心是下面的启动行:
"${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
使用 WebLogic Scripting Tool 时,使用以下语句启动 Node Manager:
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);
要运行此脚本,请使用:
#!/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
所用环境变量由名为 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
这对应于先前所述的目录结构。使用 WebLogic Scripting Tool 时,通过以下属性文件 (environment.properties
) 设置用户名、密码等:
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
下面是如何对密码进行加密的例子。如果要在其他环境中使用该脚本,只需更改文件 SetEnvironmentVariables.sh
和 environment.properties
。
一般来说,应在计算机启动时启动 Node Manager。本例中,我们需要了解在何处放置系统启动时将调用的自定义命令。Linux 有一个 /etc/rc.d/rc.local
文件,可以在其中放置自定义命令。
我们采用推荐的基于脚本的方式来完成此操作。基于 Unix 的系统指定所谓的运行级别;对于每个运行级别,可以定义启动某个服务的脚本。这些脚本位于 /etc/rc.d/init.d
目录下。可在系统启动时启动服务,或在系统关闭时停止服务。由 /etc/rc.d
目录中的特定目录指定不同运行级别:
启动序列如下所示:在 /etc/inittab
文件中,定义启动运行级别,调用脚本 /etc/rc.d/rc.sysinit
,然后运行 /etc/rc.d/rc
。rc
脚本查看 /etc/rc.d/rc<start-runlevel>.d
,以 stop 选项执行 K**<script-name>
脚本。之后,使用 start 选项执行 S**<script-name>
脚本。(注意:脚本按数字顺序启动,即 S10network
脚本在 S80sendmail
脚本之前执行。)
要创建 Node Manager“服务”,请使用以下脚本:
#!/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 $?
将此脚本放在 /etc/rc.d/init.d
目录中。使用 chkconfig
命令更新系统服务的运行级别信息(例如 chkconfig --add nodemanager and chkconfig nodemanager on
)。要测试设置,请关闭系统,然后再重新启动。要检查 Node Manager 是否在运行,请使用 ps -ef|grep java
或 netstat -anp|grep :5556
(假定Node Manager 监听端口 5556)。
还可以考虑将 CrashRecoveryEnabled
属性设置为“true”(允许 Node Manager 在系统崩溃后重新启动服务器),因为默认情况下此属性未启用。系统重启之后,Node Manager 检查 nodemanager.domains
文件中指定的每个受管域,以确定是否有任何服务器实例未彻底关闭。判断的依据是看是否存在任何锁定文件,这种文件在创建 WebLogic Server 进程时由 Node Manager 创建。此锁定文件包含 WebLogic Server 启动脚本的进程标识符。如果存在锁定文件,但进程 ID 未在运行,Node Manager 会尝试自动重新启动服务器。如果进程在运行,Node Manager 会执行额外的检查,访问进程中运行的管理 servlet,以验证与进程 ID 对应的进程是否为 WebLogic Server 实例。要测试进程,请启动所有服务器,然后重新启动主机。服务器重新运行之后,状态文件 (${DOMAIN_HOME}/server/${SERVER_NAME}/data/nodemanager/${SERVER_NAME}.state
) 中会包含一个 FORCE_SHUTTING_DOWN 条目。在本例中,对于控制台或 WebLogic Scripting Tool 启动的服务器,服务器会处于不兼容状态。CrashRecoveryEnabled
设置为 true,因此 Node Manager 将检测锁定文件并自动启动服务器;我们可以手动编辑状态文件并将状态设置为 SHUTDOWN,这非常适合在具有多台服务器的环境中运行。
... <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.> ...
要停止 Node Manager,我们可以使用:
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();
对于 nmConnect
,我们可以选择两种方式提供用户名和密码 — 通过属性(如以上示例),或者使用用户配置和密钥文件。对于后一种情况,必须使用 storeUserConfig
。例如:
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();
脚本运行时,可以观察到以下输出:
[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
可以这样使用存储的配置文件:
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();
Node Manager 运行时,我们可以启动管理服务器。
要通过 Node Manager 启动管理服务器,请使用 nmStart
。例如:
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();
注: 要想使用 nmStart
启动服务器,boot.properties
(在 ${DOMAIN_HOME}/servers/${ADMIN_SERVER_NAME}/security
中)必须存在。要停止管理服务器,我们可以使用:
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();
虽然我们也可以使用 nmKill
而不是 shutdown 来停止管理服务器,但使用 shutdown 命令关闭服务器时,可以更细微地进行控制,如设置一个超时,从容地关闭服务器。
通常,启动 WebLogic Server 实例时,会启动所有服务,包括 Enterprise JavaBeans (EJB)、Java 消息服务 (JMS)、Java EE Connector Architecture (JCA)、集群、部署、管理等等。但 WebLogic Server 提供了一个启动选项 (-DserverType="wlx"
),通过从启动名单中排除一部分服务,可以减少运行时的资源占用。这种启动模式可以提高 WebLogic Server 的启动速度,并减少主机上资源的占用空间。WebLogic Server 实例中启动的服务名单由服务器类型启动命令决定,它可以接受服务器类型选项。有两个服务器类型选项:
wls
— 启动所有服务(默认值)wlx
— 启动除以下服务外的所有服务: 如果 WebLogic Server 实例不需要使用这些服务,就可以运行轻型运行时,从而提高性能。
为了停止和启动域中的受管服务器,我们将使用 ServerLifeCycleRuntimeMBean
,它提供将服务器从一种状态转换到另一种状态的方法。此类只在管理服务器上实例化,可用于转换受管服务器的状态(不能用于启动管理服务器)。若要用它来启动受管服务器,必须先在每个受管服务器的主机上安装 Node Manager。要启动受管服务器,可以使用:
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();
要停止受管服务器,可以使用:
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();
使用存储的用户配置文件,还可以采用以下方式连接到管理服务器:
connect(userConfigFile=domain_home +'/admin_server_config_file.properties', userKeyFile=domain_home + '/admin_server_key_file.properties', url=admin_server_url);
以上脚本将启动和停止域中的所有受管服务器。如果只想停止某个主机上的服务器,我们需要了解 WebLogic 实例实际运行在哪个主机上。这种情况下,可以使用 ServerRuntimeMBean
,它提供了用于检索有关服务器实例的运行时信息的方法,以及用于将服务器从一种状态转换到另一种状态的方法。使用以下方式在本地停止受管服务器实例:
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();
在此,我们使用首次通过 Node Manager 启动服务器时创建的 startup.properties
文件 (${DOMAIN_HOME}/servers/${SERVER_NAME}/data/nodemanager
) 检索管理服务器 URL。startup.properties
中的 AdminURL
属性包含管理服务器的 URL。脚本运行时,可以观察到以下输出:
[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
在以上所示脚本中,我们连接到管理服务器以检索运行时信息。若遇管理服务器不可用,但我们又希望停止和启动受管服务器,则必须分别转而使用 nmKill
和 nmStart
。要以独立模式启动受管服务器,可以使用:
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);
示例如下:
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 ...
要使用 nmStart
,我们需要获得服务器名称。${DOMAIN_HOME}/servers
包含以服务器名称命名的目录,例如,本例中为:
${DOMAIN_HOME} /servers /AdminServer /coherence_server_1 /domain_bak /server_machine1.com_9001 /server_machine2.com_9002
使用 File API 获得目录的名称。要将此与 WLST 命令 nmConnect
和 nmStart
(或 nmKill
)组合,请创建如下脚本:
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();
执行此脚本时,可以观察到以下输出:
# 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.
注意文档中的注释:“若要使用 nmStart 启动服务器,boot.properties 必须存在。如果您是首次启动服务器或首次使用 Node Manager,必须手动创建该文件,或运行 nmGenBootStartupProps
命令为服务器生成 boot.properties 和 startup.properties 文件。”例如:
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.
为 Node Manager 创建一个“服务”是很好的做法,这样就可以在计算机启动时启动 Node Manager。可以考虑将 CrashRecoveryEnabled
设置为“true”,这样计算机重启时就不会有问题了。还可以考虑让 Node Manager 使用明文(而不是 ssl
)通信(如果网络实在不安全,也可以使用 ssl 并创建自己的密钥库)。为每个域设置一个 Node Manager,而不是每台计算机。通过 Node Manager 启动管理服务器,并通过管理服务器启动受管服务器。为确保 Node Manager 能够在系统崩溃后正常重启服务器,还必须启用 CrashRecoveryEnabled
。这种情况下,计算机的启动序列中只需有 Node Manager 即可。
René van Wijk
Oracle ACE 总监 René van Wijk 使用众多技术,包括 Oracle Coherence、Oracle WebLogic、Hibernate、Java 虚拟机、JBoss 和 Spring。他毕业于代尔夫特理工大学,经常通过培训、出版物以及研讨会和各种会议上的演讲活动传授知识和经验。