systemd 在 ExecStop 完成之前杀死我的进程
systemd kill my processes before ExecStop completed
我正在尝试更新我的应用程序以将其与 systemd 一起使用。
当我使用 Upstart 时,我只是创建了一个 /etc/init.d/myService 脚本:
#!/bin/bash
#chkconfig: 2345 90 10
#description: myDescription
### BEGIN INIT INFO
# Provides: myService
# Required-Start: sshd
# Required-Stop: sshd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start myService
# Description:
### END INIT INFO
SCRIPT=$(readlink -f [=10=])
lockfile="/var/lock/subsys/myService"
do_start() {
if [ -d "/var/lock/subsys" ]; then
touch $lockfile
fi
...
}
do_stop() {
...
if [ -d "/var/lock/subsys" ]; then
if [ -f "$lockfile" ]; then
rm -f $lockfile
fi
fi
}
do_status() {
...
}
case "" in
start)
do_start
exit 0
;;
stop)
do_stop
exit 0
;;
status)
do_status
exit 0
;;
restart)
do_stop
do_start
exit 0
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac
一切都很好。
注意,此脚本生成一些将在后台执行的子进程。
为了将它与 systemd 一起使用,我制作了以下服务文件 (myService.service):
[Unit]
Description=My Description
Requires=sshd.service
After=sshd.service
Before=shutdown.target reboot.target halt.target
[Service]
Type=oneshot
ExecStart=/etc/init.d/myService start
ExecStop=/etc/init.d/myService stop
RemainAfterExit=yes
KillMode=none
[Install]
WantedBy=multi-user.target
如果我运行
systemctl stop myService.service
一切正常。我的应用程序通过 /etc/init.d/myService stop 命令成功停止。
但我遇到了以下问题:
当我重新启动系统时,/etc/init.d/myService stop 正在执行,我应该通过 myService 脚本停止的进程已经杀了我应该控制很多进程(大约 7 个进程),系统不应该自行终止它。
我尝试使用 Type=forking 并将 PIDFile 指定为进程的 pidfile,它具有最长的生命周期(它应该首先开始结束最后停止),但是我的所有进程都再次终止。
有什么简单的方法可以避免杀死我的子进程吗?
已找到解决方案。
我运行 hadoop和hbase,他们的一些组件是通过ssh连接到本地主机启动的,并且通过这种方式启动的进程无法被systemd控制。
这是分布式系统的设计,但在我的例子中,工作是在一台机器上进行的。所以我已经替换为 hadoop/bin/slaves.sh
for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do
ssh $HADOOP_SSH_OPTS $slave $"${@// /\ }" \
2>&1 | sed "s/^/$slave: /" &
if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
至
for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do
eval "$@"
if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
问题已解决,现在进程显示在服务进程树中。
Hbase可能有相同的解决方案,但现在它以distributed=false开始,并且不通过ssh启动任何进程。
我正在尝试更新我的应用程序以将其与 systemd 一起使用。 当我使用 Upstart 时,我只是创建了一个 /etc/init.d/myService 脚本:
#!/bin/bash
#chkconfig: 2345 90 10
#description: myDescription
### BEGIN INIT INFO
# Provides: myService
# Required-Start: sshd
# Required-Stop: sshd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start myService
# Description:
### END INIT INFO
SCRIPT=$(readlink -f [=10=])
lockfile="/var/lock/subsys/myService"
do_start() {
if [ -d "/var/lock/subsys" ]; then
touch $lockfile
fi
...
}
do_stop() {
...
if [ -d "/var/lock/subsys" ]; then
if [ -f "$lockfile" ]; then
rm -f $lockfile
fi
fi
}
do_status() {
...
}
case "" in
start)
do_start
exit 0
;;
stop)
do_stop
exit 0
;;
status)
do_status
exit 0
;;
restart)
do_stop
do_start
exit 0
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac
一切都很好。
注意,此脚本生成一些将在后台执行的子进程。 为了将它与 systemd 一起使用,我制作了以下服务文件 (myService.service):
[Unit]
Description=My Description
Requires=sshd.service
After=sshd.service
Before=shutdown.target reboot.target halt.target
[Service]
Type=oneshot
ExecStart=/etc/init.d/myService start
ExecStop=/etc/init.d/myService stop
RemainAfterExit=yes
KillMode=none
[Install]
WantedBy=multi-user.target
如果我运行
systemctl stop myService.service
一切正常。我的应用程序通过 /etc/init.d/myService stop 命令成功停止。
但我遇到了以下问题: 当我重新启动系统时,/etc/init.d/myService stop 正在执行,我应该通过 myService 脚本停止的进程已经杀了我应该控制很多进程(大约 7 个进程),系统不应该自行终止它。
我尝试使用 Type=forking 并将 PIDFile 指定为进程的 pidfile,它具有最长的生命周期(它应该首先开始结束最后停止),但是我的所有进程都再次终止。
有什么简单的方法可以避免杀死我的子进程吗?
已找到解决方案。
我运行 hadoop和hbase,他们的一些组件是通过ssh连接到本地主机启动的,并且通过这种方式启动的进程无法被systemd控制。 这是分布式系统的设计,但在我的例子中,工作是在一台机器上进行的。所以我已经替换为 hadoop/bin/slaves.sh
for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do
ssh $HADOOP_SSH_OPTS $slave $"${@// /\ }" \
2>&1 | sed "s/^/$slave: /" &
if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
至
for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do
eval "$@"
if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
问题已解决,现在进程显示在服务进程树中。
Hbase可能有相同的解决方案,但现在它以distributed=false开始,并且不通过ssh启动任何进程。