Linux停止Java服务

Linux停止Java服务,与selenium相关问题,部署脚本方案

前言

在部署一些不经过Jenkins的SpringBoot项目时,通常是自己编写nohup的java命令启动。重新部署时,使用JDK 自带的 jps 命令或者 Linux的 ps(process status) 命令来查出服务进程 ID,然后使用 linux kill -9命令杀死特定的进程。

虽然在一般的教程或文章里,都说直接使用 kill -9 PID,其实这个是很粗暴的而且极其危险的动作。但由于程序不是关键业务,同时直接杀死在这些项目中也不会造成数据损失,也就没有过多在意。

kill -9问题原因

因为它不管程序现在有没有未处理完的事情,直接强制终止进程,这对于一些比较敏感的服务,例如金融交易等业务是致命的。

比如说程序里使用了Springboot 的 ShutdownHook 钩子函数服务,或者实现了DisposableBean的接口,来实现服务正常关闭情况时,调用某些方法。如果程序时被kill -9 结束的,这些方法就会不会被调用,进而导致某些问题。

程序中有selenium,使用kill -9的相关问题

前文有说,如果使用kill -9结束进程会使程序无法调用钩子函数。而程序在使用selenium时,往往都会使用钩子函数,在结束程序前,就chrome浏览器进程和selenium的chromedriver驱动进程结束掉,以保证下次启动selenium的正常。

所以如果程序使用了selenium,那就不能使用kill -9来结束程序进程!

解决方案

以下脚本是参考https://zhuanlan.zhihu.com/p/396444861和同事的脚本编写。

#!/bin/bash

APP_FILE=proxyIpCrawl-0.0.1-SNAPSHOT.jar

CONF_NAME=test

JAVA_OPTIONS_INITIAL=-Xms2048M

JAVA_OPTIONS_MAX=-Xmx3072M

APP_NAME=proxyIpCrawl-0.0.1

PID=0

function get_pid {
    javaps=`jps -l | grep $APP_FILE`
    if [ -n "$javaps" ]; then
       PID=`echo $javaps | awk '{print $1}'`
    else
       PID=0
    fi
}


function check_if_process_is_running {
    get_pid
    if [ $PID -ne 0 ]; then
    return 0
    fi
    return 1
}
function stop {
    echo -e "Waiting for process to stop"
    get_pid
    num=`expr $num + 1`  
    if [ $PID -ne 0 ]; then
        # 重试次数小于3次则继续尝试停止服务
        if [ "$num" -le 3 ];then
            echo "attempt to kill... num:$num"
            kill $PID
            sleep 1
        else
            # 重试次数大于3次,则强制停止
            echo "force kill..."
            # 结束Chromedriver进程
            ps aux | grep chromedriver | grep -v grep | awk '{print $2}' | xargs kill -9
            # 结束Chrome进程
            ps aux | grep chrome | grep -v grep | awk '{print $2}' | xargs kill -9
            # 结束java进程
            kill -9 $PID      
        fi
        # 检查上述命令执行是否成功
        if [ $? -eq 0 ]; then
            echo -e "kill -15 $APP_NAME run finished..."
        else
            echo -e "kill -15 $APP_NAME run failed..."
        fi

        # 重新获取进程ID,如果还存在则重试停止
        get_pid
        if [ $PID -ne 0 ]; then
            echo -e "$APP_NAME has running...retry"
            stop
        fi
    else
       echo "$APP_NAME not running"
    fi
}

case "$1" in
  status)
    if check_if_process_is_running
    then
      echo -e "$APP_NAME has running"
    else
      echo -e "$APP_NAME not ran"
    fi
    ;;
  stop)
    if ! check_if_process_is_running
    then
      echo  -e "$APP_NAME has stopped"
      exit 0
    fi
    stop
    ;;
  start)
    if check_if_process_is_running
    then
      echo -e "$APP_NAME has running"
      exit 1
    fi
    # 启动命令
    nohup java -jar $JAVA_OPTIONS_INITIAL $JAVA_OPTIONS_MAX $APP_FILE --spring.profiles.active=$CONF_NAME &
    echo -e "Starting"
    for i in {1..20}; do
        if ! check_if_process_is_running
        then
           echo -ne "."
           sleep 1
        fi
    done
    if ! check_if_process_is_running
    then
       echo  -e "$APP_NAME launch failed"
    else
       echo  -e "$APP_NAME has started"
    fi
    ;;
  restart)
    $0 stop
    if [ $? = 1 ]
    then
      exit 1
    fi
    $0 start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
esac

exit 0
  • 脚本在stop进程时,会尝试执行3次kill -15命令来结束程序进程,kill -15命令就能够让程序正常调起钩子函数让程序完成需要完成的动作。如果3次都没有结束程序在使用kill -9 强制结束进程
  • 同时为了结束selenium相关进程,在强制结束进程时,还会使用管道命令将chrome和chromedriver进程一起杀死。如果你的程序没有使用selenium,可以删除这两条管道命令,同时根据你程序的需求自行编写其他命令
  • 其他程序使用该脚本只需要修改前五个常量即可
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值