开发者

springboot项目如何在linux服务器上启动、停止脚本

目录
  • springboot在linux服务器上启动、停止脚本
  • 自动化部署之springboot项目快速启动停止脚本
    • JVM GC垃圾回收器参数设置
    • JVM参数疑问解答
    • JVM参数设置优化例子
  • 总结

    springboot在linux服务器上启动、停止脚本

    xxxx.sh

    #!/bin/bash
    cd `dirname $0`
    CUR_SHELL_DIR=`pwd`
    CUR_SHELL_NAME=`basename ${BASH_SOURCE}`
    #修改这里jar包名即可
    JAR_NAME="xxxxxxxxxxxx.jar"
    JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME
    #Java_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m"
    JAVA_MEM_OPTS=""
    #SPRING_PROFILES_ACTIV="-Dspring.profiles.active=eureka2"
    SPRING_PROFILES_ACTIV=""
    LOG_DIR=$CUR_SHELL_DIR/logs
    LOG_PATH=$LOG_DIR/${JAR_NAME}.log
    echo_help()
    {
      echo -e "syntax: sh $CUR_SHELL_NAME start|stop"
    }
    if [ -z $1 ];then
      echo_help
      exit 1
    fi
    if [ ! -d "$LOG_DIR" ];then
      mkdir "$LOG_DIR"
    fi
    if [ ! -f "$LOG_PATH" ];then
      touch "$LOG_DIR"
    fi
    if [ "$1" == "start" ];then
    # check server
      PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
      if [ -n "$PIDS" ]; then
        echo -e "ERROR: The $JAR_NAME already started and the PID is ${P编程客栈IDS}."
        exit 1
      fi
    echo "Starting the $JAR_NAME..."
      # start
      nohup java $JAVA_MEM_OPTS -jar $SPRING_PROFILES_ACTIV $JAR_PATH >> $LOG_PATH 2>&1 &
      COUNT=0
      while [ $COUNT -lt 1 ]; do
        sleep 1
        COUNT=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}' | wc -l`
        if [ $COUNT -gt 0 ]; then
          break
        fi
      done
      PIDS=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}'`
      echo "${JAR_NAME} Started and the PID is ${PIDS}."
      echo "You can check the log file in ${LOG_PATH} for details."
    elif [ "$1" == "stop" ];then
      PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
      if [ -z "$PIDS" ]; then
        echo "ERROR:The $JAR_NAME does not started!"
        exit 1
      fi
    echo -e "Stopping the $JAR_NAME..."
      for PID in $PIDS; do
        kill $PID > /dev/null 2>&1
      done
      COUNT=0
      while [ $COUNT -lt 1 ]; do
        sleep 1
        COUNT=1
        for PID in $PIDS ; do
          PID_EXIST=`ps --no-heading -p $PID`
       编程   if [ -n "$PID_EXIST" ]; then
            COUNT=0
            break
          fi
        done
      done
      echo -e "${JAR_NAME} Stopped and the PID is ${PIDS}."
    else
      echo_help
      exit 1
    fi

    以上代码只需修改jar包名即可使用

    启动jar包:

    ./xxxx.sh start

    停止 jar包

    ./xxxx.sh stop

    授权

    chmod +x xxx.sh

    自动化部署之springboot项目快速启动停止脚本

    由于项目需要编写了Spring boot启动停止脚本

    1.脚本需要于jar包放到开发者_开发培训同一个目录下面

    脚本内容如下:

    #!/bin/bash
    appName=`ls|grep .jar$`
    if [ -z $appName ]
    then
      echo "Pleashttp://www.devze.come check that this script and your jar-package is in the same directory!"
      exit 1
    fi
    killForceFlag=$2
    function start()
    {
      count=`ps -ef |grep java|grep $appName|wc -l`
      if [ApXpg $count != 0 ];then
        echo "Maybe $appName is running, please check it..."
      else
        echo "The $appName is starting..."
        nohup java -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms512M -Xmx4G -jar $appName > /dev/null 2>&1 &
      fi
    }
    function stop()
    {
      appId=`ps -ef |grep java|grep $appName|awk '{print $2}'`
      if [ -z $appId ]
      then
        echo "Maybe $appName not running, please check it..."
      else
        echo -n "The $appName is stopping..."
        if [ "$killForceFlag" == "-f" ]
        then
          echo "by force"
          kill -9 $appId
        else
          echo
          kill $appId
        fi
      fi
    }
    function status()
    {
      appId=`ps -ef |grep java|grep $appName|awk '{print $2}'`
      if [ -z $appId ]
      then
        echo -e "\033[31m Not running \033[0m"
      else
        echo -e "\033[32m Running [$appId] \033[0m"
      fi
    }
    function restart()
    {
      stop
      for i in {3..1}
      do
        echo -n "$i "
        sleep 1
      done
      echo 0
      start
    }
    function usage()
    {
      echo "Usage: $0 {start|stop|restart|status|stop -f}"
      echo "Example: $0 start"
      exit 1
    }
    case $1 in
      start)
      start;;
      stop)
      stop;;
      restart)
      restart;;
      status)
      status;;
      *)
      usage;;
    esac

    2.使用说明

    app.sh脚本为快速启动应用和关闭应用的脚本,使用方法如下:

    首先,将你需要发布的jar包,和含有上述内容的脚本app.sh,上传至linux服务器,注意两者必须处于同一目录,并且该目录下只有一个jar包,并给与app.sh相应执行权限,chmod 777 app.sh

    然后就可以执行脚本,命令如下:

    命令作用
    ./app.sh start启动应用
    ./app.sh stop关闭应用
    ./app.sh restart重启应用
    ./app.sh status查看应用状态
    ./app.sh stop -f强制kill应用进程

    注意,重新发布应用时,先stop再上传替换jar包哦。

    JVM GC垃圾回收器参数设置

    JVM给出了3种选择:串行收集器、并行收集器、并发收集器。串行收集器只适用于小数据量的情况,所以生产环境的选择主要是并行收集器和并发收集器。

    默认情况下JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数。JDK5.0以后,JVM会根据当前系统配置进行智能判断。

    串行收集器

    • -XX:+UseSerialGC:设置串行收集器。并行收集器(吞吐量优先)
    • -XX:+UseParallelGC:设置为并行收集器。此配置仅对年轻代有效。即年轻代使用并行收集,而年老代仍使用串行收集。
    • -XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时有多少个线程一起进行垃圾回收。此值建议配置与CPU数目相等。
    • -XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0开始支持对年老代并行收集。
    • -XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间(单位毫秒)。如果无法满足此时间,JVM会自动调整年轻代大小,以满足此时间。
    • -XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动调整年轻代Eden区大小和Survivor区大小的比例,以达成目标系统规定的最低响应时间或者收集频率等指标。此参数建议在使用并行收集器时,一直打开。

    并发收集器(响应时间优先)

    • -XX:+UseConcMarkSweepGC:即cms收集,设置年老代为并发收集。CMS收集是JDK1.4后期版本开始引入的新GC算法。它的主要适合场景是对响应时间的重要性需求大于对吞吐量的需求,能够承受垃圾回收线程和应用线程共享CPU资源,并且应用中存在比较多的长生命周期对象。CMS收集的目标是尽量减少应用的暂停时间,减少Full GC发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代内存。
    • -XX:+UseParNewGC:设置年轻代为并发收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此参数。
    • -XX:CMSFullGCsBeforeCompaction=0:由于并发收集器不对内存空间进行压缩和整理,所以运行一段时间并行收集以后会产生内存碎片,内存使用效率降低。此参数设置运行0次Full GC后对内存空间进行压缩和整理,即每次Full GC后立刻开始压缩和整理内存。
    • -XX:+UsecmsCompactAtFullCollection:打开内存空间的压缩和整理,在Full GC后执行。可能会影响性能,但可以消除内存碎片。
    • -XX:+CMSIncrementalMode:设置为增量收集模式。一般适用于单CPU情况。
    • -XX:CMSInitiatingOccupancyFraction=70:表示年老代内存空间使用到70%时就开始执行CMS收集,以确保年老代有足够的空间接纳来自年轻代的对象,避免Full GC的发生。

    其它垃圾回收参数

    • -XX:+ScavengeBeforeFullGC:年轻代GC优于Full GC执行。
    • -XX:-DisableExplicitGC:不响应 System.gc() 代码。
    • -XX:+UseThreadPriorities:启用本地线程优先级API。即使 java.lang.Thread.setPriority() 生效,不启用则无效。
    • -XX:SoftRefLRUPolicyMSPerMB=0:软引用对象在最后一次被访问后能存活0毫秒(JVM默认为1000毫秒)。
    • -XX:TargetSurvivorRatio=90:允许90%的Survivor区被占用(JVM默认为50%)。提高对于Survivor区的使用率。

    JVM参数疑问解答

    -Xmn,-XX:NewSize/-XX:MaxNewSize,-XX:NewRatio 3组参数都可以影响年轻代的大小,混合使用的情况下,优先级是什么?

    如下:

    • 高优先级:-XX:NewSize/-XX:MaxNewSize
    • 中优先级:-Xmn(默认等效 -Xmn=-XX:NewSize=-XX:MaxNewSize=?)
    • 低优先级:-XX:NewRatio

    推荐使用-Xmn参数,原因是这个参数简洁,相当于一次设定 NewSize/MaxNewSIze,而且两者相等,适用于生产环境。-Xmn 配合 -Xms/-Xmx,即可将堆内存布局完成。

    -Xmn参数是在JDK 1.4 开php始支持。

    JVM参数设置优化例子

    1. 承受海量访问的动态Web应用

    服务器配置:8 CPU, 8G MEM, JDK 1.6.X

    参数方案:

    -server -Xmx3550m -Xms3550m -Xmn1256m -Xss128k -XX:SurvivorRatio=6 -XX:MaxPermSize=256m -XX:ParallelGCThreads=8 -XX:MaxTenuringThreshold=0 -XX:+UseConcMarkSweepGC

    调优说明:

    • -Xmx-Xms 相同以避免JVM反复重新申请内存。-Xmx 的大小约等于系统内存大小的一半,即充分利用系统资源,又给予系统安全运行的空间。
    • -Xmn1256m 设置年轻代大小为1256MB。此值对系统性能影响较大,Sun官方推荐配置年轻代大小为整个堆的3/8。
    • -Xss128k 设置较小的线程栈以支持创建更多的线程,支持海量访问,并提升系统性能。
    • -XX:SurvivorRatio=6 设置年轻代中Eden区与Survivor区的比值。系统默认是8,根据经验设置为6,则2个Survivor区与1个Eden区的比值为2:6,一个Survivor区占整个年轻代的1/8。
    • -XX:ParallelGCThreads=8 配置并行收集器的线程数,即同时8个线程一起进行垃圾回收。此值一般配置为与CPU数目相等。
    • -XX:MaxTenuringThreshold=0 设置垃圾最大年龄(在年轻代的存活次数)。如果设置为0的话,则年轻代对象不经过Survivor区直接进入年老代。对于年老代比较多的应用,可以提高效率;如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。根据被海量访问的动态Web应用之特点,其内存要么被缓存起来以减少直接访问DB,要么被快速回收以支持高并发海量请求,因此其内存对象在年轻代存活多次意义不大,可以直接进入年老代,根据实际应用效果,在这里设置此值为0。
    • -XX:+UseConcMarkSweepGC 设置年老代为并发收集。CMS(ConcMarkSweepGC)收集的目标是尽量减少应用的暂停时间,减少Full GC发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代内存,适用于应用中存在比较多的长生命周期对象的情况。

    2. 内部集成构建服务器案例

    高性能数据处理的工具应用

    服务器配置:1 CPU, 4G MEM, JDK 1.6.X

    参数方案:

    -server -XX:PermSize=196m -XX:MaxPermSize=196m -Xmn320m -Xms768m -Xmx1024m

    调优说明:

    • -XX:PermSize=196m -XX:MaxPermSize=196m 根据集成构建的特点,大规模的系统编译可能需要加载大量的Java类到内存中,所以预先分配好大量的持久代内存是高效和必要的。
    • -Xmn320m 遵循年轻代大小为整个堆的3/8原则。
    • -Xms768m -Xmx1024m 根据系统大致能够承受的堆内存大小设置即可。

    脚本中可以修改的地方:

    19行: nohup java -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms512M -Xmx4G -jar $appName > /dev/null 2>&1 &

    这是最终jar的启动命令,在这里你需要对gc、Xms、Xmx等针对你机器的实际情况修改,还可以添加你所需要的启动参数等。

    56行: for i in {3..1}

    这里是设置restart的时候等待的时间,因为有的项目在3秒之内可能没有办法正常停止,所以可以调整为5秒,保证应用确实正常停止后再启动

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜