#!/bin/sh
#
#該腳本為Linux下啟動java程式的通用腳本。即可以作為開機自啟動service腳本被調用,
#也可以作為啟動java程式的獨立腳本來使用。
#警告!!!:該腳本stop部分使用系統kill指令來強制終止指定的java程式程序。
#在殺死程序前,未作任何條件檢查。在某些情況下,如程式正在進行檔案或資料庫寫操作,
#可能會造成資料丢失或資料不完整。如果必須要考慮到這類情況,則需要改寫此腳本,
#增加在執行kill指令前的一系列檢查。
#
###################################
# 以下這些注釋設定可以被chkconfig指令讀取
# chkconfig: - 99 50
# description: Java程式啟動腳本
# processname: test
# config: 如果需要的話,可以配置
###################################
#環境變量及程式執行參數
#需要根據實際環境以及Java程式名稱來修改這些參數
#JDK所在路徑
JAVA_HOME="/usr/java/jdk1.8.0_102"
#執行程式啟動所使用的系統使用者,考慮到安全,推薦不使用root帳号
#RUNNING_USER=portal
#Java程式所在的目錄(classes的上一級目錄)
APP_HOME=/opt/tmp/geecuser/geec_calculate
#需要啟動的Java主程式(main方法類)
APP_MAINCLASS=com.ai.core.start.Main
#拼湊完整的classpath參數,包括指定lib目錄下所有的jar
CLASSPATH=$APP_HOME/classes
for i in "$APP_HOME"/lib/*.jar; do
CLASSPATH="$CLASSPATH":"$i"
done
#java虛拟機啟動參數
JAVA_OPTS="-ms1024m -mx1024m -Xmn512m -Djava.awt.headless=true -XX:MaxPermSize=256m"
#(函數)判斷程式是否已啟動
#說明:
#使用JDK自帶的JPS指令及grep指令組合,準确查找pid
#jps 加 l 參數,表示顯示java的完整包路徑
#使用awk,分割出pid ($1部分),及Java程式名稱($2部分)
#初始化psid變量(全局)
psid=0
checkpid() {
javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`
if [ -n "$javaps" ]; then
psid=`echo $javaps | awk '{print $1}'`
else
psid=0
fi
}
#(函數)啟動程式
#1. 首先調用checkpid函數,重新整理$psid全局變量
#2. 如果程式已經啟動($psid不等于0),則提示程式已啟動
#3. 如果程式沒有被啟動,則執行啟動指令行
#4. 啟動指令執行後,再次調用checkpid函數
#5. 如果步驟4的結果能夠确認程式的pid,則列印[OK],否則列印[Failed]
#注意:echo -n 表示列印字元後,不換行
#注意: "nohup 某指令 >/dev/null 2>&1 &" 的用法
start() {
checkpid
if [ $psid -ne 0 ]; then
echo "================================"
echo "warn: $APP_MAINCLASS already started! (pid=$psid)"
echo -n "Starting $APP_MAINCLASS ..."
JAVA_CMD="nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >$APP_HOME/log/nohup 2>&1 &"
eval $JAVA_CMD
checkpid
if [ $psid -ne 0 ]; then
echo "(pid=$psid) [OK]"
else
echo "[Failed]"
fi
#(函數)停止程式
#2. 如果程式已經啟動($psid不等于0),則開始執行停止,否則,提示程式未運作
#3. 使用kill -9 pid指令進行強制殺死程序
#4. 執行kill指令行緊接其後,馬上檢視上一句指令的傳回值: $?
#5. 如果步驟4的結果$?等于0,則列印[OK],否則列印[Failed]
#6. 為了防止java程式被啟動多次,這裡增加反複檢查程序,反複殺死的處理(遞歸調用stop)。
#注意: 在shell程式設計中,"$?" 表示上一句指令或者一個函數的傳回值
stop() {
echo -n "Stopping $APP_MAINCLASS ...(pid=$psid) "
kill -9 $psid
if [ $? -eq 0 ]; then
echo "[OK]"
stop
echo "warn: $APP_MAINCLASS is not running"
#(函數)檢查程式運作狀态
#2. 如果程式已經啟動($psid不等于0),則提示正在運作并表示出pid
#3. 否則,提示程式未運作
status() {
if [ $psid -ne 0 ]; then
echo "$APP_MAINCLASS is running! (pid=$psid)"
echo "$APP_MAINCLASS is not running"
#(函數)列印系統環境參數
info() {
echo "System Information:"
echo "****************************"
echo `head -n 1 /etc/issue`
echo `uname -a`
echo
echo "JAVA_HOME=$JAVA_HOME"
echo `$JAVA_HOME/bin/java -version`
echo "APP_HOME=$APP_HOME"
echo "APP_MAINCLASS=$APP_MAINCLASS"
#讀取腳本的第一個參數($1),進行判斷
#參數取值範圍:{start|stop|restart|status|info}
#如參數不在指定範圍之内,則列印幫助資訊
case "$1" in
'start')
start
;;
'stop')
stop
;;
'restart')
start
'status')
status
'info')
info
*)
echo "Usage: $0 {start|stop|restart|status|info}"
exit 1
esac
exit 0