#!/bin/bash
#jar包与脚本文件需存放在同一目录

#字体颜色
CO_RED='\e[31m'
CO_GREEN='\e[32m'
CO_YELLOW='\e[33m'
CO_BLUE='\e[34m'
CO_PINK='\e[35m'
CO_END='\e[0m'

#设置命令
JAVA_CMD="${JAVA_HOME}/bin/java"
#JAVA_JPS_CMD="${JAVA_HOME}/bin/jps"

#获取脚本文件工作目录
CUR_DIR="$(
  cur=$(dirname "$0")
  cd "$cur" || {
    echo "Failure"
    exit 1
  }
  pwd
)"
#设置启动jar包
SERVICE_NAME="admin.jar"
#默认端口号
PORT="8080"
#设置jar包名称
PROJECT_NAME="${SERVICE_NAME%.*}"
#本地配置目录
LOCATION_CONFIG_DIR="${CUR_DIR}/config/"
#日志文件目录
LOG_DIR="${CUR_DIR}/logs"
#默认日志文件路径
LOG_FILE="/data/log-center/dev/${PROJECT_NAME}_${PORT}/server.log"
#扩展参数 可配置spring参数
EXTEND_OPTS=""
CUSTOM_LOG=false
while getopts ":p:cs" opt; do
  case ${opt} in
  p)
    #自定义端口
    PORT=${OPTARG}
    EXTEND_OPTS="--server.port=${OPTARG}"
    ;;
  c)
    #使用本地配置文件
    EXTEND_OPTS="${EXTEND_OPTS} --spring.config.location=${LOCATION_CONFIG_DIR}"
    ;;
  s)
    CUSTOM_LOG=true
    #设置自定义日志文件路径
    LOG_FILE="${LOG_DIR}/server_${PORT}.log"
    ;;
  ?)
    echo "Unknown parameter"
    exit 1
    ;;
  esac
done

#JVM参数
JVM_OPTS="-server \
-Duser.timezone=Asia/Shanghai \
-Xms4g \
-Xmx4g \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=256m \
-XX:+UseG1GC \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=${LOG_DIR}/dump/${PROJECT_NAME}_${PORT}-OOM.hprof"

#使用java命令获取JDK版本
java_version() {
  ${JAVA_CMD} -version 2>&1 | sed '1!d' | awk '{print $3}' | sed -e 's/"//g' | awk -F '.' '{print $1}'
}

if [ 1 -eq "$(java_version)" ]; then
  JVM_OPTS="${JVM_OPTS} -XX:+PrintGCDetails \
  -XX:+PrintGCDateStamps \
  -XX:+PrintTenuringDistribution \
  -XX:+PrintGCApplicationStoppedTime \
  -Xloggc:${LOG_DIR}/gc/gc_${PORT}-%t.log "
else
  JVM_OPTS="${JVM_OPTS} -Xlog:gc*:file=${LOG_DIR}/gc/gc_${PORT}.log:time,pid,tags:filecount=32,filesize=64m"
fi


#使用jps命令java程序获取pid
java_process_id() {
  #${JAVA_JPS_CMD} | grep "$1" | head -n1 | awk '{ print $1 }'
  ps -ef | grep "java" | grep "${SERVICE_NAME}" | grep "${PORT}" | awk '{ print $2 }'
}

#创建日志文件目录
pre_logs_dir() {
  if [ ! -d "${LOG_DIR}" ]; then
    mkdir "${LOG_DIR}"
    mkdir "${LOG_DIR}/gc"
    mkdir "${LOG_DIR}/dump"
  fi
}

showName="${CO_BLUE}${PROJECT_NAME}_${PORT}${CO_END}"

#启动jar包
jar_start() {
  #获取服务状态
  local pidTemp="$(java_process_id)"
  if [ -n "${pidTemp}" ]; then
    #服务存活就查看状态
    jar_status
  else
    #服务不存活就执行启动指令
    local cmd="${JAVA_CMD} ${JVM_OPTS} -jar ${CUR_DIR}/${SERVICE_NAME} ${EXTEND_OPTS}"

    # 执行命令
    if [ ${CUSTOM_LOG} = true ]; then
        #把日志输出至指定路径
        nohup $cmd >${LOG_FILE} 2>&1 &
    else
        #默认丢弃日志
        #nohup在进行文件重定向的时候,>表示覆盖,>>表示追加。
        nohup $cmd >/dev/null 2>&1 &
    fi
    # 找到服务pid
    local pid="$(java_process_id)"
    echo -e "try to start ${showName}, PID: ${CO_PINK}$pid${CO_END}"
    sleep 3
    jar_status
  fi
}

#获取jar包运行状态
jar_status() {
  local pid="$(java_process_id)"
  if [ -n "${pid}" ]; then
    ## server status
    local serverStatus="$(grep "Started .*Application in .* seconds" "${LOG_FILE}" | tail -n1)"
    local port=${PORT}
    #port="$(grep "initialized with port(s):" "${LOG_FILE}" | tail -n1 | awk -F ':' '{ print $2 }' | awk '{ print $1 }')"

    if [ "${serverStatus}" == "" ]; then
      echo -e "${showName} is ${CO_GREEN}running${CO_END}, PID ${CO_PINK}${pid}${CO_END}, server is ${CO_YELLOW}preparing${CO_END}."
    else
      echo -e "${showName} is ${CO_GREEN}running${CO_END}, PID ${CO_PINK}${pid}${CO_END}, server is ${CO_GREEN}ready${CO_END} in port ${CO_BLUE}${port}${CO_END}."
      echo -e "${serverStatus}"
    fi
  else
    echo -e "${showName} is ${CO_RED}not running${CO_END}"
  fi
}

# 停止jar包
jar_stop() {
  local pid="$(java_process_id)"
  local cmd="kill -15 ${pid}"
  if [ -n "${pid}" ]; then
    echo -e "stopping ${showName} PID ${CO_PINK}${pid}${CO_END}"
    $cmd
  else
    echo -e "${showName} is ${CO_RED}not running${CO_END}"
  fi
}

jar_restart() {
  echo -e "try restart ${showName}"
  jar_stop
  while true; do
    if [ -n "$(java_process_id)" ]; then
      echo -e "${showName} is ${CO_RED}stopping${CO_END}, Please wait"
      sleep 3
    else
      jar_start
      break
    fi
  done
}

jar_halt() {
  local pid="$(java_process_id)"
  local cmd="kill -9 ${pid}"
  if [ -n "${pid}" ]; then
    echo -e "forced stop ${showName} PID ${CO_PINK}${pid}${CO_END}"
    $cmd
  else
    echo -e "${showName} is ${CO_RED}not running${CO_END}"
  fi
}

# 删除已解析的参数
shift $((OPTIND-1))

# 程序命令
case "$1" in
start)
  pre_logs_dir
  jar_start
  ;;
stop)
  jar_stop
  ;;
restart)
  jar_restart
  ;;
status)
  jar_status
  ;;
halt)
  jar_halt
  ;;
*)
  echo -e "Usage: ${CO_GREEN}$0 {start | -p 8080 -c -s start | -p 8080 stop | -p 8080 -c restart | -p 8080 status | -p 8080 halt}${CO_END}"
  exit 1
  ;;
esac
exit 0