1.配置jdk环境(Linux)
一般在普通用户下的 ~/.bash_profile 或者在 /etc/profile 最后添加如下语句:
export JAVA_HOME=/opt/app/jdk1.8.0_162/
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
2.配置文件
activemq.xml
ActiveMQ的主配置文件,其中有部分配置有所修改以适应我的程序。
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- START SNIPPET: example -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- Allows us to use system properties as variables in this configuration file -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.properties</value>
</property>
</bean>
<!-- Allows accessing the server log -->
<bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false" scope="singleton"
init-method="start" destroy-method="stop">
</bean>
<!--
The <broker> element is used to configure the ActiveMQ broker.
-->
<!-- brokerName 设置broker的名字,默认是localhost,注意在网络上必须是唯一的。
dataDirectory 设置持久化文件目录,默认为activemq的apache-activemq-5.11.1/data目录。
-->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- 这里使用通配符">",用于递归地匹配从这个名称开始的任何目的地 -->
<policyEntry topic=">" >
<!-- The constantPendingMessageLimitStrategy is used to prevent
slow topic consumers to block producers and affect other consumers
by limiting the number of messages that are retained
For more information, see:
http://activemq.apache.org/slow-consumer-handling.html
-->
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
<!-- 我自己添加的一个policyEntry(DLQ) -->
<policyEntry queue=">" >
<deadLetterStrategy>
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<!--
The managementContext is used to configure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses the MBean server that is started by
the JVM. For more information, see:
http://activemq.apache.org/jmx.html
-->
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
<!--
Configure message persistence for the broker. The default persistence
mechanism is the KahaDB store (identified by the kahaDB tag).
For more information, see:
http://activemq.apache.org/persistence.html
-->
<!--
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
-->
<!-- 这个persistenceAdapter是我添加的,使用MySQL来持久化存储 -->
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#MySQL-DS"/>
</persistenceAdapter>
<!--
The systemUsage controls the maximum amount of space the broker will
use before disabling caching and/or slowing down producers. For more information, see:
http://activemq.apache.org/producer-flow-control.html
-->
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
<!--
The transport connectors expose ActiveMQ over a given protocol to
clients and other brokers. For more information, see:
http://activemq.apache.org/configuring-transports.html
-->
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<!-- The transport connectors ActiveMQ will listen to following transportConnector -->
<!-- 注释掉其他transportConnector,只配置openwire,允许其他进程来访问本机的所有地址上的61616端口。以及一些链接属性的配置 -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=3000&wireFormat.maxFrameSize=209715200&wireFormat.maxInactivityDuration=600000"/>
<!--
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=5000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=5000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=5000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=5000&wireFormat.maxFrameSize=104857600"/>
-->
</transportConnectors>
<!-- destroy the spring context on shutdown to stop jetty -->
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
</shutdownHooks>
</broker>
<!-- 这个bean("MySQL-DS") 就是前面添加的persistenceAdapter("MySQL-DS")的具体消息持久化方式,如jdbc的参数,属性等-->
<bean id="MySQL-DS" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/activemq?relaxAutoCommit=true&autoReconnect=true&failOverReadOnly=false&socketTimeout=5000"/>
<property name="username" value="mquser"/>
<property name="password" value="Inteplay007"/>
<!--property name="maxActive" value="350"/-->
<property name="poolPreparedStatements" value="true"/>
</bean>
<!--
Enable web consoles, REST and Ajax APIs and demos
The web consoles requires by default login, you can disable this in the jetty.xml file
Take a look at ${ACTIVEMQ_HOME}/conf/jetty.xml for more details
-->
<!-- 代表从 jetty.xml文件中导入其他配置。 -->
<import resource="jetty.xml"/>
</beans>
<!-- END SNIPPET: example -->
通配符
.用于在路径中分隔名称*用于匹配路径中的任何名称>用于递归地匹配从这个名称开始的任何目的地
关于通配符详细参见:http://activemq.apache.org/wildcards.html
jetty-realm.properties
定义可以访问web(console,demo等)的用户密码[角色]。
一般要修改默认的密码,或者防火墙关闭8161端口禁止访问。
# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin
user: user, user
jmx.access 和 jmx.password
配置jmx访问的账户密码
3.启动脚本 activemq
位于:apache-activemq-5.11.1/bin/
3.1 INIT INFO 系统服务脚本头
activemq通过命令 activemq start 启动之后,以系统服务的方式在后台运行。
以下是脚本的开头,这个是系统服务系统的方式
#!/bin/sh
### BEGIN INIT INFO
# Provides: activemq
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Default-Start: 3 5
# Default-Stop: 0 1 6
# Short-Description: Starts ActiveMQ
# Description: Starts ActiveMQ Message Broker Server
### END INIT INFO
定义两个变量,分别记录命令行的所有参数和执行选项。
# ------------------------------------------------------------------------
# IMPROVED DEBUGGING (execute with bash -x)
# export PS4=' ${BASH_SOURCE}:${LINENO}(${FUNCNAME[0]}) '
#
# Backup invocation parameters
COMMANDLINE_ARGS="$@"
EXEC_OPTION=""
3.2 几个帮助函数
setCurrentUser()用于将当前用户赋值给CUSER变量,以便脚本里使用。
# ------------------------------------------------------------------------
# HELPERS
# a simple helper to get the current user
setCurrentUser(){
CUSER="`whoami 2>/dev/null`"
# Solaris hack
if [ ! $? -eq 0 ]; then
CUSER="`/usr/ucb/whoami 2>/dev/null`"
fi
}
pathCanonical()用于获得规范的路径,摒除系统的差异。
# get a canonical path, macosx and slowlaris does not support radlink -f :-)
pathCanonical() {
local dst="${1}"
while [ -h "${dst}" ] ; do
ls=`ls -ld "${dst}"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
dst="$link"
else
dst="`dirname "${dst}"`/$link"
fi
done
local bas="`basename "${dst}"`"
local dir="`dirname "${dst}"`"
if [ "$bas" != "$dir" ]; then
dst="`pathCanonical "$dir"`/$bas"
fi
echo "${dst}" | sed -e 's#//#/#g' -e 's#/\./#/#g' -e 's#/[^/]*/\.\./#/#g'
}
getActiveMQHome() 用于获取ActiveMQ的安装路径。先通过pathCanonical()获取到启动脚本的bin路径,再获取到上一级的home目录。pwd的选项-P,是为了避免所有的符号链接。
# a simple helper to get the activemq installation dir
getActiveMQHome(){
# get the real path to the binary
local REAL_BIN="`pathCanonical $0`"
local REAL_DIR="`dirname $REAL_BIN`/../"
REAL_DIR="`cd $REAL_DIR && pwd -P`"
if [ -z "$REAL_DIR" ];then
echo 'ERROR: unable to find real installtion path fo activemq, you have to define ACTIVEMQ_HOME manually in the config' >&2
exit 1
fi
echo "$REAL_DIR/"
}
3.3 几个帮助判断
配置MQ的安装目录,如果脚本启动之前的环境里没有定义ACTIVEMQ_HOME变量,则将getActiveMQHome函数获取到的路径赋值给它。
base目录,如果环境历里设置了ACTIVEMQ_BASE变量则用之,否则将ACTIVEMQ_HOME赋值给她。
# Active MQ installation dir
if [ -z "$ACTIVEMQ_HOME" ] ; then
ACTIVEMQ_HOME="`getActiveMQHome`"
fi
# Active MQ base dir
if [ -z "$ACTIVEMQ_BASE" ] ; then
ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi
先配置用户级的classpath,脚本这里使用或者脚本外部调用。
再配置MQ的classpath,将外部lib添加到ACTIVEMQ_USER_CLASSPATH之前,合起来作为ACTIVEMQ_CLASSPATH。
# Configure user specified classpath here or externally using this variable
if [ -z "$ACTIVEMQ_USER_CLASSPATH" ] ; then
ACTIVEMQ_USER_CLASSPATH=""
fi
# ActiveMQ Classpath configuration
ACTIVEMQ_CLASSPATH="$ACTIVEMQ_BASE/../lib/:$ACTIVEMQ_USER_CLASSPATH"
MQ配置文件目录,如果变量ACTIVEMQ_CONF未配置,且老的写法ACTIVEMQ_CONFIG_DIR也未配置,则将$ACTIVEMQ_BASE/conf赋值给它。
# Active MQ configuration directory
if [ -z "$ACTIVEMQ_CONF" ] ; then
# For backwards compat with old variables we let ACTIVEMQ_CONFIG_DIR set ACTIVEMQ_CONF
if [ -z "$ACTIVEMQ_CONFIG_DIR" ] ; then
ACTIVEMQ_CONF="$ACTIVEMQ_BASE/conf"
else
ACTIVEMQ_CONF="$ACTIVEMQ_CONFIG_DIR"
fi
fi
MQ可以配置一个非root权限的用户,如果ACTIVEMQ_USER变量没有指定,则不改变,默认为当前用户。
# Configure a user with non root privileges, if no user is specified do not change user
if [ -z "$ACTIVEMQ_USER" ] ; then
ACTIVEMQ_USER=""
fi
MQ的数据目录,持久化目录,也存储了log。
如果ACTIVEMQ_DATA变量未指定,且老写法ACTIVEMQ_DATA_DIR也未指定,则将$ACTIVEMQ_BASE/data赋值给ACTIVEMQ_DATA。
# Active MQ data directory
if [ -z "$ACTIVEMQ_DATA" ] ; then
# For backwards compat with old variables we let ACTIVEMQ_DATA_DIR set ACTIVEMQ_DATA
if [ -z "$ACTIVEMQ_DATA_DIR" ] ; then
ACTIVEMQ_DATA="$ACTIVEMQ_BASE/data"
else
ACTIVEMQ_DATA="$ACTIVEMQ_DATA_DIR"
fi
fi
MQ的tmp目录
if [ -z "$ACTIVEMQ_TMP" ] ; then
ACTIVEMQ_TMP="$ACTIVEMQ_BASE/tmp"
fi
如果$ACTIVEMQ_DATA目录不存在,则将当前用户保存到CUSER变量。
如果$ACTIVEMQ_USER不为空或者$ACTIVEMQ_USER与$CUSER相同,则直接创建该目录;
或者如果当前用户id等于0(即root的id),则需要使用指定用户$ACTIVEMQ_USER的权限来创建该目录。
if [ ! -d "$ACTIVEMQ_DATA" ]; then
setCurrentUser
if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
mkdir $ACTIVEMQ_DATA
elif [ "`id -u`" = "0" ];then
su -c "mkdir $ACTIVEMQ_DATA" - $ACTIVEMQ_USER;
fi
fi
MQ的PID文件路径
# Location of the pidfile
if [ -z "$ACTIVEMQ_PIDFILE" ]; then
ACTIVEMQ_PIDFILE="$ACTIVEMQ_DATA/activemq.pid"
fi
上面的是一些基础环境的获取,下面介绍配置的加载。
3.4 加载配置
对于使用实例时的加载,一般没用到。我就说没有实例时,配置文件的路径ACTIVEMQ_CONFIGS有多个,分别是"/etc/default/activemq","$HOME/.activemqrc","$ACTIVEMQ_HOME/bin/env"。
# ------------------------------------------------------------------------
# LOAD CONFIGURATION
# CONFIGURATION
# For using instances
if ( basename $0 | grep "activemq-instance-" > /dev/null);then
INST="`basename $0|sed 's/^activemq-instance-//;s/\.sh$//'`"
ACTIVEMQ_CONFIGS="/etc/default/activemq-instance-${INST} $HOME/.activemqrc-instance-${INST}"
echo "INFO: Using alternative activemq configuration files: $ACTIVEMQ_CONFIGS"
else
ACTIVEMQ_CONFIGS="/etc/default/activemq $HOME/.activemqrc $ACTIVEMQ_HOME/bin/env"
fi
加载activemq配置,先将标志CONFIG_LOAD设置为no。
遍历$ACTIVEMQ_CONFIGS里面的配置,一般只有env是存在的,env是个shell脚本,可在里面修改一些配置,里面的配置将会覆盖启动脚本里获取到的配置。
( . $ACTIVEMQ_CONFIG >/dev/null 2>&1 ) 执行之后,判断状态码,为0则再次执行 . $ACTIVEMQ_CONFIG ,并将标志CONFIG_LOAD设置为yes 。关于使用点加脚本的方式执行的说明,参见附录1。
# load activemq configuration
CONFIG_LOAD="no"
for ACTIVEMQ_CONFIG in $ACTIVEMQ_CONFIGS;do
if [ -f "$ACTIVEMQ_CONFIG" ] ; then
( . $ACTIVEMQ_CONFIG >/dev/null 2>&1 )
if [ "$?" != "0" ];then
echo "ERROR: There are syntax errors in '$ACTIVEMQ_CONFIG'"
exit 1
else
echo "INFO: Loading '$ACTIVEMQ_CONFIG'"
. $ACTIVEMQ_CONFIG
CONFIG_LOAD="yes"
break
fi
fi
done
执行上面这个程序后,在启动脚本的环境下的变量里多了如下一些变量(可通过set命令查看)
ACTIVEMQ_CONFIG=/opt/app/apache-activemq-5.11.1/bin/env
ACTIVEMQ_KILL_MAXSECONDS=30
ACTIVEMQ_OPTS='-Xms1G -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/login.config'
ACTIVEMQ_OPTS_MEMORY='-Xms1G -Xmx1G'
ACTIVEMQ_QUEUEMANAGERURL='--amqurl tcp://localhost:61616'
ACTIVEMQ_SSL_OPTS=
ACTIVEMQ_SUNJMX_CONTROL=
ACTIVEMQ_SUNJMX_START=' -Dcom.sun.management.jmxremote'
ACTIVEMQ_USER=
JAVACMD=/opt/app/jdk1.8.0_162/bin/java
通过标志变量CONFIG_LOAD值为yes来通知加载了默认配置。
# inform user that default configuration is loaded, no suitable configfile found
if [ "$CONFIG_LOAD" != "yes" ];then
echo "INFO: Using default configuration";
echo " Configurations are loaded in the following order: $ACTIVEMQ_CONFIGS"
echo
fi
设置变量ACTIVEMQ_OPTS
(ACTIVEMQ_OPTS和ACTIVEMQ_OPTS_MEMORY都可以在env脚本里设置)
if [ -z "$ACTIVEMQ_OPTS" ] ; then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi
3.5 针对不同操作系统的适配
其他也写java项目,如tomcat的启动脚本里面也有类似的内容。
我的环境是linux系统,所以这些内容都不会执行到。
# ------------------------------------------------------------------------
# OS SPECIFIC SUPPORT
OSTYPE="unknown"
case "`uname`" in
CYGWIN*) OSTYPE="cygwin" ;;
Darwin*)
OSTYPE="darwin"
if [ -z "$JAVA_HOME" ] && [ "$JAVACMD" = "auto" ];then
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
fi
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched
if [ "$OSTYPE" = "cygwin" ]; then
[ -n "$ACTIVEMQ_HOME" ] &&
ACTIVEMQ_HOME="`cygpath --unix "$ACTIVEMQ_HOME"`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`cygpath --unix "$JAVA_HOME"`"
[ -n "$ACTIVEMQ_CLASSPATH" ] &&
ACTIVEMQ_CLASSPATH="`cygpath --path --unix "$ACTIVEMQ_CLASSPATH"`"
fi
3.6 寻找java命令的路径
JAVACMD从env脚本继承而来值为"auto"。
如果JAVACMD为空或者等于"auto",则
如果JAVA_HOME非空(我们一般在配置jdk环境的时候就指定了JAVA_HOME),则
如果 "$JAVA_HOME/jre/sh/java" 可执行,则将其赋值给JAVACMD;否则将"$JAVA_HOME/bin/java"赋值给他。
一般jdk里jre/bin下没有sh目录,所以一般找到的就是$JAVA_HOME/bin/java。
# Detect the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
fi
fi
如果还是没有找到java的位置,则使用which命令来查找java。如果找到了,则代表环境变量里找得到java,JAVACMD就直接使用java。
# Hm, we still do not know the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] || [ ! -x "$JAVACMD" ] ; then
JAVACMD=`which java 2> /dev/null `
if [ -z "$JAVACMD" ] ; then
JAVACMD=java
fi
fi
如果$JAVACMD 还不存在或不可执行,就报错,退出进程。
# Stop here if no java installation is defined/found
if [ ! -x "$JAVACMD" ] ; then
echo "ERROR: Configuration variable JAVA_HOME or JAVACMD is not defined correctly."
echo " (JAVA_HOME='$JAVA_HOME', JAVACMD='$JAVACMD')"
exit 1
fi
如果$JAVACMD可执行,就跳过上一个判断,向终端的标准输出打印使用的$JAVACMD。
echo "INFO: Using java '$JAVACMD'"
如果经过前面的配置,$ACTIVEMQ_BASE还是为空,则把$ACTIVEMQ_HOME赋值给它。
if [ -z "$ACTIVEMQ_BASE" ] ; then
ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi
如果是在windows下的cygwin环境中启动的本脚本,则在相应的变量前添加"cygpath --windows"前缀。
# For Cygwin, switch paths to Windows format before running java if [ "$OSTYPE" = "cygwin" ]; then
if [ "$OSTYPE" = "cygwin" ];then
ACTIVEMQ_HOME="`cygpath --windows "$ACTIVEMQ_HOME"`"
ACTIVEMQ_BASE="`cygpath --windows "$ACTIVEMQ_BASE"`"
ACTIVEMQ_CONF="`cygpath --windows "$ACTIVEMQ_CONF"`"
ACTIVEMQ_DATA="`cygpath --windows "$ACTIVEMQ_DATA"`"
ACTIVEMQ_CLASSPATH=`cygpath --path --windows "$ACTIVEMQ_CLASSPATH"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`cygpath --windows "$JAVA_HOME"`"
CYGHOME="`cygpath --windows "$HOME"`"
ACTIVEMQ_TMP="`cygpath --windows "$ACTIVEMQ_TMP"`"
if [ -n "$CYGHOME" ]; then
ACTIVEMQ_CYGWIN="-Dcygwin.user.home=\"$CYGHOME\""
fi
fi
3.7 设置默认cpasspath
在AMQ的安装配置目录前添加实例配置目录,以便先获取实例的相关配置。
# Set default classpath
# Add instance conf dir before AMQ install conf dir to pick up instance-specific classpath entries first
ACTIVEMQ_CLASSPATH="${ACTIVEMQ_CONF}:${ACTIVEMQ_CLASSPATH}"
如果系统是cygwin,则删除反斜杠以防止引用问题。
if [ "$OSTYPE" = "cygwin" ];then
# remove training backslashes to prevent quoting problems
ACTIVEMQ_CLASSPATH="`echo ${ACTIVEMQ_CLASSPATH}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_HOME="`echo ${ACTIVEMQ_HOME}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_BASE="`echo ${ACTIVEMQ_BASE}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_CONF="`echo ${ACTIVEMQ_CONF}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_DATA="`echo ${ACTIVEMQ_DATA}|sed '~s,[\\]*$,,g'`"
fi
3.8 功能:启动AMQ的jar文件
@ARG1 :pid文件名,如果本参数指定了,函数invokeJar()启动的java进程将在后台以服务的方式运行,并且这个文件存储着新建的进程pid。
标准输出和错误输出都将被抑制。
@RET :出现错误则为0
注意:本函数使用了许多全局定义的变量。
- 如果$ACTIVEMQ_USER设置了,本函数就尝试使用指定的用户启动进程。
3.8.1 函数:invokeJar()
如果${ACTIVEMQ_HOME}/bin/activemq.jar 不存在则报错,存在则继续。
然后调用函数setCurrentUser设置当前用户给变量$CUSER。
如果$ACTIVEMQ_USER为空或者等于当前用户$CUSER,则添加前缀"sh -c "和后缀";";
再如果id为0,即root,就要使用指定用户的前缀"su -s /bin/sh -c "和后缀" - $ACTIVEMQ_USER",然后向终端输出提示信息,告知更改了执行用户。
然后才是执行java程序。
【条件一】
如果$TASK_TODO(本函数的第二个参数)非空并且不等于stop,则
如果$ACTIVEMQ_OUT(继承自env脚本)为空,则赋值为"/dev/null"。(其实env里面就已经这样判断并赋值了,为什么这里还要来一遍??)
还记得最开始的EXEC_OPTION变量吗,为空。这里以它为开头,从$DOIT_PREFIX到$DOIT_POSTFIX这一句才是真正的执行启动AMQ的jar的语句。
然后用RET变量来保存执行结束状态。
【条件二】
再如果$TASK_TODO非空且等于stop,则
用SPID变量来保存本函数的第一个参数${PIDFILE}的值。
然后也是真正的意义上的启动语句。
并用RET来保存结束状态。
【条件三】
否则
执行并保存结束状态。
函数的最后是返回变量$RET。
我们需要注意区分上面红色字体的三个条件下的启动参数间的差异。
# Start the ActiveMQ JAR
#
#
# @ARG1 : the name of the PID-file
# If specified, this function starts the java process in background as a daemon
# and stores the pid of the created process in the file.
# Output on stdout/stderr will be supressed if this parameter is specified
# @RET : If unless 0 something went wrong
#
# Note: This function uses a lot of globally defined variables
# - if $ACTIVEMQ_USER is set, the function tries starts the java process whith the specified user
invokeJar(){
PIDFILE="$1"
TASK_TODO="$2"
RET="1"
if [ ! -f "${ACTIVEMQ_HOME}/bin/activemq.jar" ];then
echo "ERROR: '${ACTIVEMQ_HOME}/bin/activemq.jar' does not exist, define ACTIVEMQ_HOME in the config"
exit 1
fi
setCurrentUser
if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
DOIT_PREFIX="sh -c "
DOIT_POSTFIX=";"
elif [ "`id -u`" = "0" ];then
DOIT_PREFIX="su -s /bin/sh -c "
DOIT_POSTFIX=" - $ACTIVEMQ_USER"
echo "INFO: changing to user '$ACTIVEMQ_USER' to invoke java"
fi
# Execute java binary
if [ -n "$TASK_TODO" ] && [ "$TASK_TODO" != "stop" ];then
if [ -z "$ACTIVEMQ_OUT" ]; then
ACTIVEMQ_OUT="/dev/null"
fi
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
-Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
-Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
-Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
-Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS >> $ACTIVEMQ_OUT 2>&1 &
RET=\"\$?\"; APID=\"\$!\";
echo \$APID > "${PIDFILE}";
echo \"INFO: pidfile created : '${PIDFILE}' (pid '\$APID')\";exit \$RET" $DOIT_POSTFIX
RET="$?"
elif [ -n "$TASK_TODO" ] && [ "$TASK_TODO" = "stop" ];then
SPID="`cat "${PIDFILE}"`"
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
-Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
-Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
-Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
-Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS --pid $SPID &
RET=\"\$?\"; APID=\"\$!\";
echo \$APID > "${PIDFILE}.stop"; exit \$RET" $DOIT_POSTFIX
RET="$?"
else
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
-Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
-Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
-Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
-Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS" $DOIT_POSTFIX
RET="$?"
fi
return $RET
}
3.9 功能:检查ActiveMQ是否在运行
@RET : 0 => activemq 进程正在运行中
1 => $ACTIVEMQ_PIDFILE中进程ID不存在了
2 => PID文件相关错误
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称(全路径)
3.9.1 函数:checkRunning()
如果$ACTIVEMQ_PIDFILE文件存在,则
如果$ACTIVEMQ_PIDFILE文件的值为空,则报错“PID文件存在但是不包含PID”。
将$ACTIVEMQ_PIDFILE文件的值赋值给ACTIVEMQ_PID。
ps -p 来探测该PID的进程是否存在,并用RET来保存,$RET不为0,则本函数return 0;$RET为0,则本函数return 1。
否则
本函数return 1 。
# Check if ActiveMQ is running
#
# @RET : 0 => the activemq process is running
# 1 => process id in $ACTIVEMQ_PIDFILE does not exist anymore
# 2 => something is wrong with the pid file
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
checkRunning(){
if [ -f "$ACTIVEMQ_PIDFILE" ]; then
if [ -z "`cat $ACTIVEMQ_PIDFILE`" ];then
echo "ERROR: Pidfile '$ACTIVEMQ_PIDFILE' exists but contains no pid"
return 2
fi
ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
RET="`ps -p "${ACTIVEMQ_PID}"|grep java`" #ps -p 的用法见附录2
if [ -n "$RET" ];then
return 0;
else
return 1;
fi
else
return 1;
fi
}
3.9.2 函数:checkStopRunning()
AMQ在停止的时候,会启动一个进程来停止服务,本函数就是检测这个stop进程的状态。
stop进程产生的PID文件以".stop"结尾。相关逻辑判断与checkRunning函数类似。
checkStopRunning(){
PID_STOP="${ACTIVEMQ_PIDFILE}.stop"
if [ -f "$PID_STOP" ]; then
if [ -z "`cat $PID_STOP`" ];then
echo "ERROR: Pidfile os stop process '$PID_STOP' exists but contains no pid"
return 2
fi
THEPID=`cat ${PID_STOP}`
RET=`ps -p $THEPID|grep java`
if [ -n "$RET" ];then
return 0;
else
return 1;
fi
else
return 1;
fi
}
3.10 功能:检查ActiveMQ是否运行
@RET : 0 => activemq进程运行
1 => activemq进程没有运行
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称()全路径
调用checkRunning函数,判断函数结束状态,如果为0,则进程在运行,于是将文件$ACTIVEMQ_PIDFILE里保存值赋值给PID变量,并且以return 0 结束本函数。
3.10.1 函数 : invoke_status()
# Check if ActiveMQ is running
#
# @RET : 0 => the activemq process is running
# 1 => the activemq process is not running
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
invoke_status(){
if ( checkRunning );then
PID="`cat $ACTIVEMQ_PIDFILE`"
echo "ActiveMQ is running (pid '$PID')"
exit 0
fi
echo "ActiveMQ not running"
exit 1
}
3.11 功能 : ActiveMQ如果没有运行则启动
@RET : 0 => 进程正在启动或者已经启动
!0 => 出错
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称()全路径
- $ACTIVEMQ_OPTS : 附加选项
- $ACTIVEMQ_SUNJMX_START : JMX设定的选项
- $ACTIVEMQ_SSL_OPTS : SSL加密相关的选项
调用checkRunning函数,判断函数结束状态,如果为0,则进程在运行,并打印信息到终端。
然后使用ACTIVEMQ_OPTS添加一些选项,
调用invokeJar函数,pid文件,start参数 启动AMQ进程。
这里的start是invokeJar函数的第二个参数,也就是前面说的该函数内部的TASK_TODO,且是执行jar文件的第一个条件情况(见前面红色字体部分)
3.11.1 函数 : invoke_start()
# Start ActiveMQ if not already running
#
# @RET : 0 => is now started, is already started
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
# - $ACTIVEMQ_OPTS : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS : options for SSL encryption
invoke_start(){
if ( checkRunning );then
PID="`cat $ACTIVEMQ_PIDFILE`"
echo "INFO: Process with pid '$PID' is already running"
exit 0
fi
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""
echo "INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details"
invokeJar "$ACTIVEMQ_PIDFILE" start
exit "$?"
}
3.12 功能 : 后台启动ActiveMQ(debug模式)
本函数以调试模式启动consle,方便观察输出。
@RET : 0 => 启动
1 => 已经启动
!0 => 报错
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称()全路径
- $ACTIVEMQ_OPTS : 附加选项
- $ACTIVEMQ_SUNJMX_START : JMX设定的选项
- $ACTIVEMQ_SSL_OPTS : SSL加密相关的选项
调用checkRunning函数检查进程状态,没有运行才继续下去。
同样要添加一些选项到ACTIVEMQ_OPTS。
COMMANDLINE_ARGS是传递给启动脚本的,
3.12.1 函数 : invoke_console()
在前台运行AMQ,通常用于调试。
@RET : 0 => was started
1 => was already started (我去,"was started"和"was already started "怎么区分开,英语不好)
!0 => 出错 (我想问,上面1不也是非0吗,不属于这一类?)
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称()全路径
- $ACTIVEMQ_OPTS : 附加选项
- $ACTIVEMQ_SUNJMX_START : JMX设定的选项
- $ACTIVEMQ_SSL_OPTS : SSL加密相关的选项
在函数invoke_console中
如果 checkRunning 为真,则打印错误,告诉AMQ已经在运行,并退出函数。
ACTIVEMQ_OPTS追加一些内容。
COMMANDLINE_ARGS 删除以console开头的字段。
EXEC_OPTION赋值为"exec"。
打印一些 INFO 。
保存当前shell进程的PID到文件 $ACTIVEMQ_PIDFILE 。
以文件$ACTIVEMQ_PIDFILE作为参数执行函数invokeJar,也就是使用启动脚本的PID来最为新启动的jar进程的PID。在前面该函数的开头有说明。
使用变量 RET 记录invokeJar函数退出状态。
打印 INFO : 移除PID文件 $ACTIVEMQ_PIDFILE。
最后再以前面invokeJar函数退出状态最为本函数的退出状态。
# Start ActiveMQ in foreground (for debugging)
#
# @RET : 0 => was started
# 1 => was already started
# !0 => somthing went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
# - $ACTIVEMQ_OPTS : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS : options for SSL encryption
invoke_console(){
if ( checkRunning );then
echo "ERROR: ActiveMQ is already running"
exit 1
fi
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""
COMMANDLINE_ARGS="start `echo $COMMANDLINE_ARGS|sed 's,^console,,'`"
EXEC_OPTION="exec"
echo "INFO: Starting in foreground, this is just for debugging purposes (stop process by pressing CTRL+C)"
echo "INFO: Creating pidfile $ACTIVEMQ_PIDFILE"
echo "$$" > "$ACTIVEMQ_PIDFILE"
invokeJar "$ACTIVEMQ_PIDFILE"
RET="$?"
echo "INFO: removing pidfile $ACTIVEMQ_PIDFILE"
exit "$RET"
}
3.13 功能 : Kill ActiveMQ
杀死 ActiveMQ
3.13.1 函数 : invoke_kill()
kill ActiveMQ 进程。
@RET : 0 => 成功停止
!0 => 停止失败
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称()全路径
在函数invoke_kill中
如果 checkRunning 为真,则
将文件${ACTIVEMQ_PIDFILE}中的PID号赋值给变量ACTIVEMQ_PID
打印提示信息,已经发送SIGKILL信号到该PID进程。
真正执行kill命令。"kill -KILL"与"kill -9"等价。强制杀死进程。
记录kill命令退出状态。
强制删除文件 ${ACTIVEMQ_PIDFILE} 。
以kill的退出状态最为本函数的退出状态。
否则
打印 INFO,没有运行,什么也不做。
以0退出本函数。
# Kill ActiveMQ
# @RET : 0 => stop was successful
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
invoke_kill(){
if ( checkRunning ); then
ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
echo "INFO: sending SIGKILL to pid '$ACTIVEMQ_PID'"
kill -KILL $ACTIVEMQ_PID
RET="$?"
rm -f "${ACTIVEMQ_PIDFILE}"
return $RET
fi
echo "INFO: not running, nothing to do"
return 0
}
3.14 功能 : Stop ActiveMQ
停止 ActiveMQ
3.14.1 函数 : invoke_stop()
停止 ActiveMQ 进程。(这个stop和前面的kill,不都是停止么?)
@RET : 0 => 停止成功
!0 => 停止失败
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_PIDFILE : PID文件名称()全路径
- $ACTIVEMQ_KILL_MAXSECONDS : 一个秒为单位的数字,是在jmx接口发送shutdonw信号后,broker停止所耗费的时间。
在函数invoke_stop中
首先把RET置为1。
如果 checkRunning 为真,则
opts后面追加ssl的opts。
COMMANDLINE_ARGS后面追加ACTIVEMQ_SUNJMX_CONTROL。
文件$ACTIVEMQ_PIDFILE里的PID号赋值给变量ACTIVEMQ_PID。
以两个参数"$ACTIVEMQ_PIDFILE" "stop" 来执行函数 invokeJar。
保存invokeJar执行退出状态。
把FOUND置为0,i置为0.
打印 INFO, 等待至少 $ACTIVEMQ_KILL_MAXSECONDS秒的常规进程停止操作。
当 $i 小于或等于 $ACTIVEMQ_KILL_MAXSECONDS 时,则
如果 checkStopRunning 不为真,则
如果 checkRunning 不为真,则
打印完成 并把 FOUND置为1。
否则
break退出循环。
如果 checkRunning 为真,则
休眠1秒,并打印一个"."号。
否则
打印TERMINATED,并把FOUND置为1。
变量i加1。
<while循环结束>
如果 FOUND不为1,则
打印 INFO,常规停止不成功,发送SIGKILL信号到jar进程。
执行函数invoke_kill。 (这里我们可以看出,invoke_stop函数是完整的停止操作,而invoke_kill函数是常规停止操作失败而强制杀死进程的擦做)
保存invoke_kill函数的退出状态。
再如果 "$ACTIVEMQ_PIDFILE" 文件存在,则
打印错误,没有或者过期PID号在文件 "$ACTIVEMQ_PIDFILE"里。
打印INFO,移除文件"$ACTIVEMQ_PIDFILE"。
否则,
打印 ActiveMQ没有运行。
以0退出本函数。
删除文件"$ACTIVEMQ_PIDFILE"和"$ACTIVEMQ_DATA/stop.pid"。
最后用前面的RET来退出本函数。
# Stop ActiveMQ
# @RET : 0 => stop was successful
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
# - $ACTIVEMQ_KILL_MAXSECONDS : the number of seconds to wait for termination of broker after sending
# shutdown signal by jmx interface
invoke_stop(){
RET="1"
if ( checkRunning );then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"
COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"
ACTIVEMQ_PID="`cat $ACTIVEMQ_PIDFILE`"
invokeJar "$ACTIVEMQ_PIDFILE" "stop"
RET="$?"
FOUND="0"
i=0
echo "INFO: Waiting at least $ACTIVEMQ_KILL_MAXSECONDS seconds for regular process termination of pid '$ACTIVEMQ_PID' : "
while [ "$i" -le "$ACTIVEMQ_KILL_MAXSECONDS" ]; do
if [ ! checkStopRunning ];then
if [ ! checkRunning ]; then
echo " FINISHED"
FOUND="1"
fi
break
fi
if (checkRunning);then
sleep 1
printf "."
else
echo " TERMINATED"
FOUND="1"
break
fi
i="`expr $i + 1`"
done
if [ "$FOUND" -ne "1" ];then
echo
echo "INFO: Regular shutdown not successful, sending SIGKILL to process"
invoke_kill
RET="$?"
fi
elif [ -f "$ACTIVEMQ_PIDFILE" ];then
echo "ERROR: No or outdated process id in '$ACTIVEMQ_PIDFILE'"
echo
echo "INFO: Removing $ACTIVEMQ_PIDFILE"
else
echo "ActiveMQ not running"
exit 0
fi
rm -f "$ACTIVEMQ_PIDFILE" >/dev/null 2>&1
rm -f "$ACTIVEMQ_DATA/stop.pid" >/dev/null 2>&1
exit $RET
}
3.15 功能 : 在一个运行中的ActiveMQ实例上调用一个任务
3.15.1 函数 : invoke_task()
在一个运行的AMQ实例上调用一个任务
$1 : "checkforrunning",如果activemq没有运行则不调用任务,否则要调用任务。
@RET : 0 => 成功
!1 => 错误
注意 : 本函数使用了全局定义的变量
- $ACTIVEMQ_QUEUEMANAGERURL : 队列管理器的url
- $ACTIVEMQ_OPTS : 附加选项
- $ACTIVEMQ_SUNJMX_START : JMX设定的选项
- $ACTIVEMQ_SSL_OPTS : SSL加密相关的选项
在函数invoke_task里
定义一个局部变量CHECKRUNNING来保存传递给本函数的第一个参数。
在opts后追加ssl的opts。
如果CHECKRUNNING等于"checkforrunning",则
如果 checkRunning不为真,则
打印 “AMQ没有运行”并退出函数。
再如果 CHECKRUNNING 等于 "checkfornotrunning" ,则
如果 checkRunning 为真,则
打印 “AMQ 正在运行” 并 退出函数。
调用所有java二进制程序中的任务。
如果参数 $1 等于 "browse" 或 $ACTIVEMQ_QUEUEMANAGERURL 不为空,则
将 $COMMANDLINE_ARGS 里以browse开头的字段删除,同变量$ACTIVEMQ_QUEUEMANAGERURL 一起赋值给变量 COMMANDLINE_ARGS ;
再如果 $1 等于 "query" 或 $ACTIVEMQ_QUEUEMANAGERURL 不为空,则
将 $COMMANDLINE_ARGS 里以query开头的字段删除,同变量 $ACTIVEMQ_SUNJMX_CONTROL一起赋值给变量 COMMANDLINE_ARGS ;
否则
$ACTIVEMQ_SUNJMX_CONTROL 直接追加到 $COMMANDLINE_ARGS。
执行函数invokeJar,并用"$ACTIVEMQ_PIDFILE"作为参数。
实用变量RET记录上面函数的退出状态,并最为本函数的退出状态。
# Invoke a task on a running ActiveMQ instance
#
# $1 : "checkforrunning", do not invoke the task if activemq is not
# active
# <other>, invoke task always
# @RET : 0 => successful
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_QUEUEMANAGERURL : The url of the queuemanager
# - $ACTIVEMQ_OPTS : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS : options for SSL encryption
invoke_task(){
local CHECKRUNNING="$1"
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"
if [ "$CHECKRUNNING" = "checkforrunning" ];then
if ( ! checkRunning );then
echo "Activemq is not running."
exit 1
fi
elif [ "$CHECKRUNNING" = "checkfornotrunning" ];then
if ( checkRunning );then
echo "Activemq is running."
exit 1
fi
fi
# call task in java binary
if [ "$1" = "browse" ] && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
COMMANDLINE_ARGS="$ACTIVEMQ_QUEUEMANAGERURL `echo $COMMANDLINE_ARGS|sed 's,^browse,,'`"
elif [ "$1" = "query" ] && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
COMMANDLINE_ARGS="$ACTIVEMQ_SUNJMX_CONTROL `echo $COMMANDLINE_ARGS|sed 's,^query,,'`"
else
COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"
fi
invokeJar "$ACTIVEMQ_PIDFILE"
RET="$?"
exit $RET
}
3.16 函数 : show_help()
脚本的帮助函数
show_help() {
invokeJar "$ACTIVEMQ_PIDFILE"|sed "s,Usage: Main,Usage: $0,"
cat << EOF
Tasks provided by the sysv init script:
kill - terminate instance in a drastic way by sending SIGKILL
restart - stop running instance (if there is one), start new instance
console - start broker in foreground, useful for debugging purposes
status - check if activemq process is running
Configuration of this script:
The configuration of this script is read from the following files:
$ACTIVEMQ_CONFIGS
This script searches for the files in the listed order and reads the first available file.
Modify $ACTIVEMQ_BASE/bin/env or create a copy of that file on a suitable location.
To use additional configurations for running multiple instances on the same operating system
rename or symlink script to a name matching to activemq-instance-<INSTANCENAME>.
This changes the configuration location to /etc/default/activemq-instance-<INSTANCENAME> and
\$HOME/.activemqrc-instance-<INSTANCENAME>.
EOF
exit 1
}
3.17 主逻辑
主逻辑部分,主要是根据输入的脚本参数,调用相应的前面的函数,以完成相关的功能。
# ------------------------------------------------------------------------
# MAIN
# show help
if [ -z "$1" ];then
show_help
fi
case "$1" in
status)
invoke_status
;;
restart)
if ( checkRunning );then
$0 stop
echo
fi
$0 start
$0 status
;;
start)
invoke_start
;;
console)
invoke_console
exit $?
;;
stop)
invoke_stop
exit $?
;;
kill)
invoke_kill
exit $?
;;
*)
invoke_task
exit $?
esac
附录
附录1 : source script | . scritpt | script 三种方式执行shell脚本的区别
前两种方式 :source script 和 . scritpt 执行脚本效果一样,在当前shell里执行后,script里面的变量在当前shell生效,而不会产生子shell,不会只有在子shell中script的变量才有效。
第三种方式:直接运行脚本,则脚本中的变量只在子shell中有效,在当前shell中无效。
详细说明,请参见文章《在Linux中用source,dot(.)和直接用脚本文件名执行shell脚本的区别》。
附录2 : ps -p 的用法
[inteplay@localhost data]$ ps -p 1174
PID TTY TIME CMD
[inteplay@localhost data]$ ps -p 11749
PID TTY TIME CMD
11749 ? 2-17:37:04 java
-p 用来指定进程pid,如果没有该进程则只显示列头,且通过java运行的进程,CMD似乎都显示的是java。
附录3 : activemq启动脚本完整内容
#!/bin/sh
### BEGIN INIT INFO
# Provides: activemq
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Default-Start: 3 5
# Default-Stop: 0 1 6
# Short-Description: Starts ActiveMQ
# Description: Starts ActiveMQ Message Broker Server
### END INIT INFO
# ------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------------------
#
# This script controls standalone Apache ActiveMQ service processes.
# To ensure compatibility to macosx and cygwin we do not utilize
# lsb standard infrastructure for controlling daemons like
# "start-stop-daemon".
#
# See also http://activemq.apache.org/activemq-command-line-tools-reference.html
# for additional commandline arguments
#
# System variables for this script, like ACTIVEMQ_OPTS and ACTIVEMQ_OPTS_MEMORY,
# can be configured in 'env' script located in this directory.
#
# For more information on configuring the script, see http://activemq.apache.org/unix-shell-script.html
#
#
# Authors:
# Marc Schoechlin <ms@256bit.org>
# ------------------------------------------------------------------------
# IMPROVED DEBUGGING (execute with bash -x)
# export PS4=' ${BASH_SOURCE}:${LINENO}(${FUNCNAME[0]}) '
#
# Backup invocation parameters
COMMANDLINE_ARGS="$@"
EXEC_OPTION=""
# ------------------------------------------------------------------------
# HELPERS
# a simple helper to get the current user
setCurrentUser(){
CUSER="`whoami 2>/dev/null`"
# Solaris hack
if [ ! $? -eq 0 ]; then
CUSER="`/usr/ucb/whoami 2>/dev/null`"
fi
}
# get a canonical path, macosx and slowlaris does not support radlink -f :-)
pathCanonical() {
local dst="${1}"
while [ -h "${dst}" ] ; do
ls=`ls -ld "${dst}"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
dst="$link"
else
dst="`dirname "${dst}"`/$link"
fi
done
local bas="`basename "${dst}"`"
local dir="`dirname "${dst}"`"
if [ "$bas" != "$dir" ]; then
dst="`pathCanonical "$dir"`/$bas"
fi
echo "${dst}" | sed -e 's#//#/#g' -e 's#/\./#/#g' -e 's#/[^/]*/\.\./#/#g'
}
# a simple helper to get the activemq installation dir
getActiveMQHome(){
# get the real path to the binary
local REAL_BIN="`pathCanonical $0`"
local REAL_DIR="`dirname $REAL_BIN`/../"
REAL_DIR="`cd $REAL_DIR && pwd -P`"
if [ -z "$REAL_DIR" ];then
echo 'ERROR: unable to find real installtion path fo activemq, you have to define ACTIVEMQ_HOME manually in the config' >&2
exit 1
fi
echo "$REAL_DIR/"
}
# Active MQ installation dir
if [ -z "$ACTIVEMQ_HOME" ] ; then
ACTIVEMQ_HOME="`getActiveMQHome`"
fi
# Active MQ base dir
if [ -z "$ACTIVEMQ_BASE" ] ; then
ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi
# Configure user specified classpath here or externally using this variable
if [ -z "$ACTIVEMQ_USER_CLASSPATH" ] ; then
ACTIVEMQ_USER_CLASSPATH=""
fi
# ActiveMQ Classpath configuration
ACTIVEMQ_CLASSPATH="$ACTIVEMQ_BASE/../lib/:$ACTIVEMQ_USER_CLASSPATH"
# Active MQ configuration directory
if [ -z "$ACTIVEMQ_CONF" ] ; then
# For backwards compat with old variables we let ACTIVEMQ_CONFIG_DIR set ACTIVEMQ_CONF
if [ -z "$ACTIVEMQ_CONFIG_DIR" ] ; then
ACTIVEMQ_CONF="$ACTIVEMQ_BASE/conf"
else
ACTIVEMQ_CONF="$ACTIVEMQ_CONFIG_DIR"
fi
fi
# Configure a user with non root privileges, if no user is specified do not change user
if [ -z "$ACTIVEMQ_USER" ] ; then
ACTIVEMQ_USER=""
fi
# Active MQ data directory
if [ -z "$ACTIVEMQ_DATA" ] ; then
# For backwards compat with old variables we let ACTIVEMQ_DATA_DIR set ACTIVEMQ_DATA
if [ -z "$ACTIVEMQ_DATA_DIR" ] ; then
ACTIVEMQ_DATA="$ACTIVEMQ_BASE/data"
else
ACTIVEMQ_DATA="$ACTIVEMQ_DATA_DIR"
fi
fi
if [ -z "$ACTIVEMQ_TMP" ] ; then
ACTIVEMQ_TMP="$ACTIVEMQ_BASE/tmp"
fi
if [ ! -d "$ACTIVEMQ_DATA" ]; then
setCurrentUser
if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
mkdir $ACTIVEMQ_DATA
elif [ "`id -u`" = "0" ];then
su -c "mkdir $ACTIVEMQ_DATA" - $ACTIVEMQ_USER;
fi
fi
# Location of the pidfile
if [ -z "$ACTIVEMQ_PIDFILE" ]; then
ACTIVEMQ_PIDFILE="$ACTIVEMQ_DATA/activemq.pid"
fi
# ------------------------------------------------------------------------
# LOAD CONFIGURATION
# CONFIGURATION
# For using instances
if ( basename $0 | grep "activemq-instance-" > /dev/null);then
INST="`basename $0|sed 's/^activemq-instance-//;s/\.sh$//'`"
ACTIVEMQ_CONFIGS="/etc/default/activemq-instance-${INST} $HOME/.activemqrc-instance-${INST}"
echo "INFO: Using alternative activemq configuration files: $ACTIVEMQ_CONFIGS"
else
ACTIVEMQ_CONFIGS="/etc/default/activemq $HOME/.activemqrc $ACTIVEMQ_HOME/bin/env"
fi
# load activemq configuration
CONFIG_LOAD="no"
for ACTIVEMQ_CONFIG in $ACTIVEMQ_CONFIGS;do
if [ -f "$ACTIVEMQ_CONFIG" ] ; then
( . $ACTIVEMQ_CONFIG >/dev/null 2>&1 )
if [ "$?" != "0" ];then
echo "ERROR: There are syntax errors in '$ACTIVEMQ_CONFIG'"
exit 1
else
echo "INFO: Loading '$ACTIVEMQ_CONFIG'"
. $ACTIVEMQ_CONFIG
CONFIG_LOAD="yes"
break
fi
fi
done
# inform user that default configuration is loaded, no suitable configfile found
if [ "$CONFIG_LOAD" != "yes" ];then
echo "INFO: Using default configuration";
echo " Configurations are loaded in the following order: $ACTIVEMQ_CONFIGS"
echo
fi
if [ -z "$ACTIVEMQ_OPTS" ] ; then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi
# ------------------------------------------------------------------------
# OS SPECIFIC SUPPORT
OSTYPE="unknown"
case "`uname`" in
CYGWIN*) OSTYPE="cygwin" ;;
Darwin*)
OSTYPE="darwin"
if [ -z "$JAVA_HOME" ] && [ "$JAVACMD" = "auto" ];then
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
fi
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched
if [ "$OSTYPE" = "cygwin" ]; then
[ -n "$ACTIVEMQ_HOME" ] &&
ACTIVEMQ_HOME="`cygpath --unix "$ACTIVEMQ_HOME"`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`cygpath --unix "$JAVA_HOME"`"
[ -n "$ACTIVEMQ_CLASSPATH" ] &&
ACTIVEMQ_CLASSPATH="`cygpath --path --unix "$ACTIVEMQ_CLASSPATH"`"
fi
# Detect the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
fi
fi
# Hm, we still do not know the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] || [ ! -x "$JAVACMD" ] ; then
JAVACMD=`which java 2> /dev/null `
if [ -z "$JAVACMD" ] ; then
JAVACMD=java
fi
fi
# Stop here if no java installation is defined/found
if [ ! -x "$JAVACMD" ] ; then
echo "ERROR: Configuration variable JAVA_HOME or JAVACMD is not defined correctly."
echo " (JAVA_HOME='$JAVA_HOME', JAVACMD='$JAVACMD')"
exit 1
fi
echo "INFO: Using java '$JAVACMD'"
if [ -z "$ACTIVEMQ_BASE" ] ; then
ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi
# For Cygwin, switch paths to Windows format before running java if [ "$OSTYPE" = "cygwin" ]; then
if [ "$OSTYPE" = "cygwin" ];then
ACTIVEMQ_HOME="`cygpath --windows "$ACTIVEMQ_HOME"`"
ACTIVEMQ_BASE="`cygpath --windows "$ACTIVEMQ_BASE"`"
ACTIVEMQ_CONF="`cygpath --windows "$ACTIVEMQ_CONF"`"
ACTIVEMQ_DATA="`cygpath --windows "$ACTIVEMQ_DATA"`"
ACTIVEMQ_CLASSPATH=`cygpath --path --windows "$ACTIVEMQ_CLASSPATH"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`cygpath --windows "$JAVA_HOME"`"
CYGHOME="`cygpath --windows "$HOME"`"
ACTIVEMQ_TMP="`cygpath --windows "$ACTIVEMQ_TMP"`"
if [ -n "$CYGHOME" ]; then
ACTIVEMQ_CYGWIN="-Dcygwin.user.home=\"$CYGHOME\""
fi
fi
# Set default classpath
# Add instance conf dir before AMQ install conf dir to pick up instance-specific classpath entries first
ACTIVEMQ_CLASSPATH="${ACTIVEMQ_CONF}:${ACTIVEMQ_CLASSPATH}"
if [ "$OSTYPE" = "cygwin" ];then
# remove training backslashes to prevent quoting problems
ACTIVEMQ_CLASSPATH="`echo ${ACTIVEMQ_CLASSPATH}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_HOME="`echo ${ACTIVEMQ_HOME}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_BASE="`echo ${ACTIVEMQ_BASE}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_CONF="`echo ${ACTIVEMQ_CONF}|sed '~s,[\\]*$,,g'`"
ACTIVEMQ_DATA="`echo ${ACTIVEMQ_DATA}|sed '~s,[\\]*$,,g'`"
fi
# Start the ActiveMQ JAR
#
#
# @ARG1 : the name of the PID-file
# If specified, this function starts the java process in background as a daemon
# and stores the pid of the created process in the file.
# Output on stdout/stderr will be supressed if this parameter is specified
# @RET : If unless 0 something went wrong
#
# Note: This function uses a lot of globally defined variables
# - if $ACTIVEMQ_USER is set, the function tries starts the java process whith the specified
# user
invokeJar(){
PIDFILE="$1"
TASK_TODO="$2"
RET="1"
if [ ! -f "${ACTIVEMQ_HOME}/bin/activemq.jar" ];then
echo "ERROR: '${ACTIVEMQ_HOME}/bin/activemq.jar' does not exist, define ACTIVEMQ_HOME in the config"
exit 1
fi
setCurrentUser
if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
DOIT_PREFIX="sh -c "
DOIT_POSTFIX=";"
elif [ "`id -u`" = "0" ];then
DOIT_PREFIX="su -s /bin/sh -c "
DOIT_POSTFIX=" - $ACTIVEMQ_USER"
echo "INFO: changing to user '$ACTIVEMQ_USER' to invoke java"
fi
# Execute java binary
if [ -n "$TASK_TODO" ] && [ "$TASK_TODO" != "stop" ];then
if [ -z "$ACTIVEMQ_OUT" ]; then
ACTIVEMQ_OUT="/dev/null"
fi
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
-Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
-Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
-Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
-Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS >> $ACTIVEMQ_OUT 2>&1 &
RET=\"\$?\"; APID=\"\$!\";
echo \$APID > "${PIDFILE}";
echo \"INFO: pidfile created : '${PIDFILE}' (pid '\$APID')\";exit \$RET" $DOIT_POSTFIX
RET="$?"
elif [ -n "$TASK_TODO" ] && [ "$TASK_TODO" = "stop" ];then
SPID="`cat "${PIDFILE}"`"
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
-Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
-Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
-Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
-Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS --pid $SPID &
RET=\"\$?\"; APID=\"\$!\";
echo \$APID > "${PIDFILE}.stop"; exit \$RET" $DOIT_POSTFIX
RET="$?"
else
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
-Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
-Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
-Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
-Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS" $DOIT_POSTFIX
RET="$?"
fi
return $RET
}
# Check if ActiveMQ is running
#
# @RET : 0 => the activemq process is running
# 1 => process id in $ACTIVEMQ_PIDFILE does not exist anymore
# 2 => something is wrong with the pid file
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
checkRunning(){
if [ -f "$ACTIVEMQ_PIDFILE" ]; then
if [ -z "`cat $ACTIVEMQ_PIDFILE`" ];then
echo "ERROR: Pidfile '$ACTIVEMQ_PIDFILE' exists but contains no pid"
return 2
fi
ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
RET="`ps -p "${ACTIVEMQ_PID}"|grep java`"
if [ -n "$RET" ];then
return 0;
else
return 1;
fi
else
return 1;
fi
}
checkStopRunning(){
PID_STOP="${ACTIVEMQ_PIDFILE}.stop"
if [ -f "$PID_STOP" ]; then
if [ -z "`cat $PID_STOP`" ];then
echo "ERROR: Pidfile os stop process '$PID_STOP' exists but contains no pid"
return 2
fi
THEPID=`cat ${PID_STOP}`
RET=`ps -p $THEPID|grep java`
if [ -n "$RET" ];then
return 0;
else
return 1;
fi
else
return 1;
fi
}
# Check if ActiveMQ is running
#
# @RET : 0 => the activemq process is running
# 1 => the activemq process is not running
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
invoke_status(){
if ( checkRunning );then
PID="`cat $ACTIVEMQ_PIDFILE`"
echo "ActiveMQ is running (pid '$PID')"
exit 0
fi
echo "ActiveMQ not running"
exit 1
}
# Start ActiveMQ if not already running
#
# @RET : 0 => is now started, is already started
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
# - $ACTIVEMQ_OPTS : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS : options for SSL encryption
invoke_start(){
if ( checkRunning );then
PID="`cat $ACTIVEMQ_PIDFILE`"
echo "INFO: Process with pid '$PID' is already running"
exit 0
fi
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""
echo "INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details"
invokeJar "$ACTIVEMQ_PIDFILE" start
exit "$?"
}
# Start ActiveMQ in foreground (for debugging)
#
# @RET : 0 => was started
# 1 => was already started
# !0 => somthing went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
# - $ACTIVEMQ_OPTS : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS : options for SSL encryption
invoke_console(){
if ( checkRunning );then
echo "ERROR: ActiveMQ is already running"
exit 1
fi
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""
COMMANDLINE_ARGS="start `echo $COMMANDLINE_ARGS|sed 's,^console,,'`"
EXEC_OPTION="exec"
echo "INFO: Starting in foreground, this is just for debugging purposes (stop process by pressing CTRL+C)"
echo "INFO: Creating pidfile $ACTIVEMQ_PIDFILE"
echo "$$" > "$ACTIVEMQ_PIDFILE"
invokeJar "$ACTIVEMQ_PIDFILE"
RET="$?"
echo "INFO: removing pidfile $ACTIVEMQ_PIDFILE"
exit "$RET"
}
# Kill ActiveMQ
# @RET : 0 => stop was successful
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
invoke_kill(){
if ( checkRunning ); then
ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
echo "INFO: sending SIGKILL to pid '$ACTIVEMQ_PID'"
kill -KILL $ACTIVEMQ_PID
RET="$?"
rm -f "${ACTIVEMQ_PIDFILE}"
return $RET
fi
echo "INFO: not running, nothing to do"
return 0
}
# Stop ActiveMQ
# @RET : 0 => stop was successful
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file
# - $ACTIVEMQ_KILL_MAXSECONDS : the number of seconds to wait for termination of broker after sending
# shutdown signal by jmx interface
invoke_stop(){
RET="1"
if ( checkRunning );then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"
COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"
ACTIVEMQ_PID="`cat $ACTIVEMQ_PIDFILE`"
invokeJar "$ACTIVEMQ_PIDFILE" "stop"
RET="$?"
FOUND="0"
i=0
echo "INFO: Waiting at least $ACTIVEMQ_KILL_MAXSECONDS seconds for regular process termination of pid '$ACTIVEMQ_PID' : "
while [ "$i" -le "$ACTIVEMQ_KILL_MAXSECONDS" ]; do
if [ ! checkStopRunning ];then
if [ ! checkRunning ]; then
echo " FINISHED"
FOUND="1"
fi
break
fi
if (checkRunning);then
sleep 1
printf "."
else
echo " TERMINATED"
FOUND="1"
break
fi
i="`expr $i + 1`"
done
if [ "$FOUND" -ne "1" ];then
echo
echo "INFO: Regular shutdown not successful, sending SIGKILL to process"
invoke_kill
RET="$?"
fi
elif [ -f "$ACTIVEMQ_PIDFILE" ];then
echo "ERROR: No or outdated process id in '$ACTIVEMQ_PIDFILE'"
echo
echo "INFO: Removing $ACTIVEMQ_PIDFILE"
else
echo "ActiveMQ not running"
exit 0
fi
rm -f "$ACTIVEMQ_PIDFILE" >/dev/null 2>&1
rm -f "$ACTIVEMQ_DATA/stop.pid" >/dev/null 2>&1
exit $RET
}
# Invoke a task on a running ActiveMQ instance
#
# $1 : "checkforrunning", do not invoke the task if activemq is not
# active
# <other>, invoke task always
# @RET : 0 => successful
# !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_QUEUEMANAGERURL : The url of the queuemanager
# - $ACTIVEMQ_OPTS : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS : options for SSL encryption
invoke_task(){
local CHECKRUNNING="$1"
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"
if [ "$CHECKRUNNING" = "checkforrunning" ];then
if ( ! checkRunning );then
echo "Activemq is not running."
exit 1
fi
elif [ "$CHECKRUNNING" = "checkfornotrunning" ];then
if ( checkRunning );then
echo "Activemq is running."
exit 1
fi
fi
# call task in java binary
if [ "$1" = "browse" ] && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
COMMANDLINE_ARGS="$ACTIVEMQ_QUEUEMANAGERURL `echo $COMMANDLINE_ARGS|sed 's,^browse,,'`"
elif [ "$1" = "query" ] && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
COMMANDLINE_ARGS="$ACTIVEMQ_SUNJMX_CONTROL `echo $COMMANDLINE_ARGS|sed 's,^query,,'`"
else
COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"
fi
invokeJar "$ACTIVEMQ_PIDFILE"
RET="$?"
exit $RET
}
show_help() {
invokeJar "$ACTIVEMQ_PIDFILE"|sed "s,Usage: Main,Usage: $0,"
cat << EOF
Tasks provided by the sysv init script:
kill - terminate instance in a drastic way by sending SIGKILL
restart - stop running instance (if there is one), start new instance
console - start broker in foreground, useful for debugging purposes
status - check if activemq process is running
Configuration of this script:
The configuration of this script is read from the following files:
$ACTIVEMQ_CONFIGS
This script searches for the files in the listed order and reads the first available file.
Modify $ACTIVEMQ_BASE/bin/env or create a copy of that file on a suitable location.
To use additional configurations for running multiple instances on the same operating system
rename or symlink script to a name matching to activemq-instance-<INSTANCENAME>.
This changes the configuration location to /etc/default/activemq-instance-<INSTANCENAME> and
\$HOME/.activemqrc-instance-<INSTANCENAME>.
EOF
exit 1
}
# ------------------------------------------------------------------------
# MAIN
# show help
if [ -z "$1" ];then
show_help
fi
case "$1" in
status)
invoke_status
;;
restart)
if ( checkRunning );then
$0 stop
echo
fi
$0 start
$0 status
;;
start)
invoke_start
;;
console)
invoke_console
exit $?
;;
stop)
invoke_stop
exit $?
;;
kill)
invoke_kill
exit $?
;;
*)
invoke_task
exit $?
esac
本文详细介绍了ActiveMQ的配置启动文件,包括配置jdk环境、配置文件如activemq.xml、jetty-realm.properties、jmx访问权限设置等。重点解析了启动脚本activemq的各个部分,如系统服务脚本头、帮助函数、启动、停止、检查运行状态等功能实现,以及如何在运行中的ActiveMQ实例上执行任务。此外,还提到了附录中关于shell脚本执行方式、ps命令的用法等知识点。
8840

被折叠的 条评论
为什么被折叠?



