zoukankan      html  css  js  c++  java
  • Springboot 打包自带启动脚本

    一直以来,我都是

    gradlew build
    java -jar xxx.jar
    

    来启动springboot项目的。今天突然发现,springboot自动封装了一个bootJar的任务脚本。

    demo: https://github.com/Ryan-Miao/Spring-Cloud-Greenwich-Demo/commit/ed47988218f59d2ca49ce5d328433985da067a14

    添加

    bootJar {
        launchScript()
    }
    

    然后

    
    gradlew xxxx:bootJar
    

    打包出来的jar文件是一个可执行的shell脚本。

    vi xxx.jar可以看到前290行的shell

    #!/bin/bash
    #
    #    .   ____          _            __ _ _
    #   /\ / ___'_ __ _ _(_)_ __  __ _    
    #  ( ( )\___ | '_ | '_| | '_ / _` |    
    #   \/  ___)| |_)| | | | | || (_| |  ) ) ) )
    #    '  |____| .__|_| |_|_| |_\__, | / / / /
    #   =========|_|==============|___/=/_/_/_/
    #   :: Spring Boot Startup Script ::
    #
    
    ### BEGIN INIT INFO
    # Provides:          service-gateway
    # Required-Start:    $remote_fs $syslog $network
    # Required-Stop:     $remote_fs $syslog $network
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: service-gateway
    # Description:       service-gateway
    # chkconfig:         2345 99 01
    ### END INIT INFO
    
    [[ -n "$DEBUG" ]] && set -x
    
    # Initialize variables that cannot be provided by a .conf file
    WORKING_DIR="$(pwd)"
    # shellcheck disable=SC2153
    [[ -n "$JARFILE" ]] && jarfile="$JARFILE"
    [[ -n "$APP_NAME" ]] && identity="$APP_NAME"
    
    # Follow symlinks to find the real jar and detect init.d script
    cd "$(dirname "$0")" || exit 1
    [[ -z "$jarfile" ]] && jarfile=$(pwd)/$(basename "$0")
    while [[ -L "$jarfile" ]]; do
      if [[ "$jarfile" =~ init.d ]]; then
        init_script=$(basename "$jarfile")
      else
        configfile="${jarfile%.*}.conf"
        # shellcheck source=/dev/null
        [[ -r ${configfile} ]] && source "${configfile}"
      fi
      jarfile=$(readlink "$jarfile")
      cd "$(dirname "$jarfile")" || exit 1
      jarfile=$(pwd)/$(basename "$jarfile")
    done
    jarfolder="$( (cd "$(dirname "$jarfile")" && pwd -P) )"
    cd "$WORKING_DIR" || exit 1
    
    # Inline script specified in build properties
    
    
    # Source any config file
    configfile="$(basename "${jarfile%.*}.conf")"
    
    # Initialize CONF_FOLDER location defaulting to jarfolder
    [[ -z "$CONF_FOLDER" ]] && CONF_FOLDER="${jarfolder}"
    # shellcheck source=/dev/null
    [[ -r "${CONF_FOLDER}/${configfile}" ]] && source "${CONF_FOLDER}/${configfile}"
    
    # ANSI Colors
    echoRed() { echo $'e[0;31m'"$1"$'e[0m'; }
    echoGreen() { echo $'e[0;32m'"$1"$'e[0m'; }
    echoYellow() { echo $'e[0;33m'"$1"$'e[0m'; }
    
    # Initialize PID/LOG locations if they weren't provided by the config file
    [[ -z "$PID_FOLDER" ]] && PID_FOLDER="/var/run"
    [[ -z "$LOG_FOLDER" ]] && LOG_FOLDER="/var/log"
    ! [[ "$PID_FOLDER" == /* ]] && PID_FOLDER="$(dirname "$jarfile")"/"$PID_FOLDER"
    ! [[ "$LOG_FOLDER" == /* ]] && LOG_FOLDER="$(dirname "$jarfile")"/"$LOG_FOLDER"
    ! [[ -x "$PID_FOLDER" ]] && echoYellow "PID_FOLDER $PID_FOLDER does not exist. Falling back to /tmp" && PID_FOLDER="/tmp"
    ! [[ -x "$LOG_FOLDER" ]] && echoYellow "LOG_FOLDER $LOG_FOLDER does not exist. Falling back to /tmp" && LOG_FOLDER="/tmp"
    
    # Set up defaults
    [[ -z "$MODE" ]] && MODE="auto" # modes are "auto", "service" or "run"
    [[ -z "$USE_START_STOP_DAEMON" ]] && USE_START_STOP_DAEMON="true"
    
    # Create an identity for log/pid files
    if [[ -z "$identity" ]]; then
      if [[ -n "$init_script" ]]; then
        identity="${init_script}"
      else
        identity=$(basename "${jarfile%.*}")_${jarfolder////}
      fi
    fi
    
    # Initialize log file name if not provided by the config file
    [[ -z "$LOG_FILENAME" ]] && LOG_FILENAME="${identity}.log"
    
    # Initialize stop wait time if not provided by the config file
    [[ -z "$STOP_WAIT_TIME" ]] && STOP_WAIT_TIME="60"
    
    # Utility functions
    checkPermissions() {
      touch "$pid_file" &> /dev/null || { echoRed "Operation not permitted (cannot access pid file)"; return 4; }
      touch "$log_file" &> /dev/null || { echoRed "Operation not permitted (cannot access log file)"; return 4; }
    }
    
    isRunning() {
      ps -p "$1" &> /dev/null
    }
    
    await_file() {
      end=$(date +%s)
      let "end+=10"
      while [[ ! -s "$1" ]]
      do
        now=$(date +%s)
        if [[ $now -ge $end ]]; then
          break
        fi
        sleep 1
      done
    }
    
    # Determine the script mode
    action="run"
    if [[ "$MODE" == "auto" && -n "$init_script" ]] || [[ "$MODE" == "service" ]]; then
      action="$1"
      shift
    fi
    
    # Build the pid and log filenames
    PID_FOLDER="$PID_FOLDER/${identity}"
    pid_file="$PID_FOLDER/${identity}.pid"
    log_file="$LOG_FOLDER/$LOG_FILENAME"
    
    # Determine the user to run as if we are root
    # shellcheck disable=SC2012
    [[ $(id -u) == "0" ]] && run_user=$(ls -ld "$jarfile" | awk '{print $3}')
    
    # Issue a warning if the application will run as root
    [[ $(id -u ${run_user}) == "0" ]] && { echoYellow "Application is running as root (UID 0). This is considered insecure."; }
    
    # Find Java
    if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then
        javaexe="$JAVA_HOME/bin/java"
    elif type -p java > /dev/null 2>&1; then
        javaexe=$(type -p java)
    elif [[ -x "/usr/bin/java" ]];  then
        javaexe="/usr/bin/java"
    else
        echo "Unable to find Java"
        exit 1
    fi
    
    arguments=(-Dsun.misc.URLClassPath.disableJarChecking=true $JAVA_OPTS -jar "$jarfile" $RUN_ARGS "$@")
    
    # Action functions
    start() {
      if [[ -f "$pid_file" ]]; then
        pid=$(cat "$pid_file")
        isRunning "$pid" && { echoYellow "Already running [$pid]"; return 0; }
      fi
      do_start "$@"
    }
    
    do_start() {
      working_dir=$(dirname "$jarfile")
      pushd "$working_dir" > /dev/null
      if [[ ! -e "$PID_FOLDER" ]]; then
        mkdir -p "$PID_FOLDER" &> /dev/null
        if [[ -n "$run_user" ]]; then
          chown "$run_user" "$PID_FOLDER"
        fi
      fi
      if [[ ! -e "$log_file" ]]; then
        touch "$log_file" &> /dev/null
        if [[ -n "$run_user" ]]; then
          chown "$run_user" "$log_file"
        fi
      fi
      if [[ -n "$run_user" ]]; then
        checkPermissions || return $?
        if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then
          start-stop-daemon --start --quiet 
            --chuid "$run_user" 
            --name "$identity" 
            --make-pidfile --pidfile "$pid_file" 
            --background --no-close 
            --startas "$javaexe" 
            --chdir "$working_dir" 
            -- "${arguments[@]}" 
            >> "$log_file" 2>&1
          await_file "$pid_file"
        else
          su -s /bin/sh -c "$javaexe $(printf ""%s" " "${arguments[@]}") >> "$log_file" 2>&1 & echo $!" "$run_user" > "$pid_file"
        fi
        pid=$(cat "$pid_file")
      else
        checkPermissions || return $?
        "$javaexe" "${arguments[@]}" >> "$log_file" 2>&1 &
        pid=$!
        disown $pid
        echo "$pid" > "$pid_file"
      fi
      [[ -z $pid ]] && { echoRed "Failed to start"; return 1; }
      echoGreen "Started [$pid]"
    }
    
    stop() {
      working_dir=$(dirname "$jarfile")
      pushd "$working_dir" > /dev/null
      [[ -f $pid_file ]] || { echoYellow "Not running (pidfile not found)"; return 0; }
      pid=$(cat "$pid_file")
      isRunning "$pid" || { echoYellow "Not running (process ${pid}). Removing stale pid file."; rm -f "$pid_file"; return 0; }
      do_stop "$pid" "$pid_file"
    }
    
    do_stop() {
      kill "$1" &> /dev/null || { echoRed "Unable to kill process $1"; return 1; }
      for i in $(seq 1 $STOP_WAIT_TIME); do
        isRunning "$1" || { echoGreen "Stopped [$1]"; rm -f "$2"; return 0; }
        [[ $i -eq STOP_WAIT_TIME/2 ]] && kill "$1" &> /dev/null
        sleep 1
      done
      echoRed "Unable to kill process $1";
      return 1;
    }
    
    force_stop() {
      [[ -f $pid_file ]] || { echoYellow "Not running (pidfile not found)"; return 0; }
      pid=$(cat "$pid_file")
      isRunning "$pid" || { echoYellow "Not running (process ${pid}). Removing stale pid file."; rm -f "$pid_file"; return 0; }
      do_force_stop "$pid" "$pid_file"
    }
    
    do_force_stop() {
      kill -9 "$1" &> /dev/null || { echoRed "Unable to kill process $1"; return 1; }
      for i in $(seq 1 $STOP_WAIT_TIME); do
        isRunning "$1" || { echoGreen "Stopped [$1]"; rm -f "$2"; return 0; }
        [[ $i -eq STOP_WAIT_TIME/2 ]] && kill -9 "$1" &> /dev/null
        sleep 1
      done
      echoRed "Unable to kill process $1";
      return 1;
    }
    
    restart() {
      stop && start
    }
    
    force_reload() {
      working_dir=$(dirname "$jarfile")
      pushd "$working_dir" > /dev/null
      [[ -f $pid_file ]] || { echoRed "Not running (pidfile not found)"; return 7; }
      pid=$(cat "$pid_file")
      rm -f "$pid_file"
      isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 7; }
      do_stop "$pid" "$pid_file"
      do_start
    }
    
    status() {
      working_dir=$(dirname "$jarfile")
      pushd "$working_dir" > /dev/null
      [[ -f "$pid_file" ]] || { echoRed "Not running"; return 3; }
      pid=$(cat "$pid_file")
      isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 1; }
      echoGreen "Running [$pid]"
      return 0
    }
    
    run() {
      pushd "$(dirname "$jarfile")" > /dev/null
      "$javaexe" "${arguments[@]}"
      result=$?
      popd > /dev/null
      return "$result"
    }
    
    # Call the appropriate action function
    case "$action" in
    start)
      start "$@"; exit $?;;
    stop)
      stop "$@"; exit $?;;
    force-stop)
      force_stop "$@"; exit $?;;
    restart)
      restart "$@"; exit $?;;
    force-reload)
      force_reload "$@"; exit $?;;
    status)
      status "$@"; exit $?;;
    run)
      run "$@"; exit $?;;
    *)
      echo "Usage: $0 {start|stop|force-stop|restart|force-reload|status|run}"; exit 1;
    esac
    
    exit 0
    

    即,在jar同目录下放一个同名的conf配置文件xxx.conf. 配置

    PID_FOLDER=./logs
    RUN_ARGS="--spring.profiles.active=dev"
    JAVA_OPTS="-Xms1024m -Xmx3072m -Dfile.encoding=UTF-8 -Denv=DEV"
    

    可以直接 sh xxxx.jar start启动了。

    对centos6

    #创建soft link
    chmod +x /path/xxx.jar
    ln -s  /path/xxx.jar  /etc/init.d/xxxx
    
    # 启动
    service xxxx start
    
    # 添加开机启动
    chkconfig --add xxx
    chkconfig xxx on
    chkconfig --list
    
    

    上述方案对手动部署springboot的项目来说很好用。打Docker镜像也可以同理设置,但对Docker镜像来说,还是直接使用java -jar更简单明了。

  • 相关阅读:
    Java 嵌套循环之九九乘法表
    Java switch语句第二种用法
    Java switch语句
    Java if-else if-else多选择结构代码
    Java if else双选择结构之计算圆的面积和周长
    Java if单选择结构---掷色子游戏
    在webstorm11中使用nodejs库的智能提示功能
    Node.JS 学习路线图
    Nodejs系列课程,从入门到进阶帮你打通全栈
    使用supervisor提高nodejs调试效率
  • 原文地址:https://www.cnblogs.com/woshimrf/p/11980923.html
Copyright © 2011-2022 走看看