systemctl 停止服务不起作用

systemctl 停止服务不起作用

我在/etc/systemd/system中编写了这个服务,名为nexusiq.service

[Unit]
Description=Nexus IQ Service
After=network.target

[Service]
Type=simple
ExecStart=/etc/init.d/nexus-iq-server start
ExecStop=/etc/init.d/nexus-iq-server stop
User=root
Restart=on-abort
TimeoutSec=600

[Install]
WantedBy=multi-user.target

/etc/init.d 中的脚本nexus-iq-server在 ExecStart 和 ExecStop 中调用,具体取决于我是否给出“start”或“stop”作为参数,执行以下操作:

NEXUS_IQ_SERVER_HOME=/apps/nexus/nexus-iq-server
VERSION=1.127.0-01
JAVA_OPTIONS="-Xmx4096m -XX:+UseG1GC"
RUN_AS_USER=root

do_start()
{
    cd $NEXUS_IQ_SERVER_HOME
    su -m $RUN_AS_USER --command "java $JAVA_OPTIONS -jar nexus-iq-server-$VERSION.jar server config.yml 2> stderr.log &"
    echo "Started nexus-iq-server"
}

do_console()
{
    cd $NEXUS_IQ_SERVER_HOME
    su -m $RUN_AS_USER --command "java $JAVA_OPTIONS -jar nexus-iq-server-$VERSION.jar server config.yml 2> stderr.log"
}

do_stop()
{
    pid=`ps aux | grep nexus-iq-server | grep '.jar server' | grep -vE '(stop|grep)' | awk '{print $2}'`
    kill $pid
    echo "Killed nexus-iq-server - PID $pid"
}

do_usage()
{
    echo "Usage: nexus-iq-server [console|start|stop]"
}

case $1 in
    console)
        do_console
        ;;
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    *)
        do_usage
        ;;
esac

我已启用该服务。

当我运行命令时: systemctl start nexusiq 正确调用分配给 ExecStart 的命令。但是,如果我运行该命令systemctl stop nexusiq,则不会调用分配给 ExecStop 的命令。

此外,如果我运行命令systemctl status nexusiq,看起来该服务处于非活动状态:

● nexusiq.service - Nexus IQ Service
   Loaded: loaded (/etc/systemd/system/nexusiq.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Wed 2021-11-17 12:56:03 CET; 16s ago
  Process: 14806 ExecStop=/etc/init.d/nexus-iq-server stop (code=exited, status=0/SUCCESS)
  Process: 14800 ExecStart=/etc/init.d/nexus-iq-server start (code=exited, status=0/SUCCESS)
 Main PID: 14800 (code=exited, status=0/SUCCESS)

Nov 17 12:56:03 nexusiq2 systemd[1]: Started Nexus IQ Service.
Nov 17 12:56:03 nexusiq2 su[14801]: (to root) root on none
Nov 17 12:56:03 nexusiq2 nexus-iq-server[14800]: Started nexus-iq-server

谁能向我解释一下造成这种情况的原因以及如何解决它?

答案1

你需要Type=forking而不是Type=simple.

手册页说:

  • 如果设置为 simple(如果指定了 ExecStart=,但 Type= 和 BusName= 均未指定,则为默认值),服务管理器将认为该单元在主服务进程分叉后立即启动。预计ExecStart=配置的进程是服务的主进程。在此模式下,如果进程向系统上的其他进程提供功能,则应在服务启动之前安装其通信通道(例如,由 systemd 通过套接字激活设置套接字),因为服务管理器将立即开始执行以下操作-up 单元,在创建主服务进程之后、执行服务的二进制文件之前。请注意,这意味着即使无法成功调用服务的二进制文件(例如,因为所选的 User= 不存在,或者服务二进制文件丢失),简单服务的 systemctl start 命令行也会报告成功。
  • 如果设置为 forking,则预计使用 ExecStart= 配置的进程将调用 fork() 作为其启动的一部分。当启动完成并且所有通信通道都建立后,父进程预计将退出。子进程继续作为主服务进程运行,当父进程退出时,服务管理器会认为该单元已启动。这是传统 UNIX 服务的行为。如果使用此设置,建议同时使用PIDFile=选项,以便systemd能够可靠地识别服务的主进程。一旦父进程退出,systemd 将继续启动后续单元。

总而言之,当/etc/init.d/nexus-iq-server start结束时,systemd things 你的服务就完成了。因此它认为它处于非活动状态(已停止)。 systemd会将残留的 java 进程视为需要清理并终止的进程。 systemctl stop不会执行任何操作,因为设备已经停止。

使用Type=forking告诉 systemdExecStart=预计会产生一个进程并退出。该生成的进程成为 systemd 跟踪的主要 PID。

相关内容