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 $0)
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 "$1" 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を停止注文する。
ところで、次のような問題が発生しました。システムを再起動すると、/etc/init.d/myServiceを停止プロセスが実行中なので停止する必要があります。私のサービススクリプトが終了しました。私は多くのプロセス(約7プロセス)を制御する必要があり、システムは自分でプロセスを終了しないでください。
Type = forkingを使用し、長寿命のプロセスのpidfileとしてPIDFileを指定しようとしましたが(最初に開始して最後に停止する必要があります)、すべてのプロセスが再び終了します。
私の子プロセスが終了するのを防ぐ簡単な方法はありますか?
問題がある場合は、root以外のユーザーがアプリケーションを実行します。
答え1
解決策が見つかりました。
私はhadoopとhbaseを実行していますが、そのコンポーネントのいくつかはlocalhostへのssh接続を介して起動され、この方法で開始されたプロセスはsystemdで制御できません。これは分散システム設計ですが、私の場合は1つのシステムで作業を行います。だから私は次に交換しました。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には同じソリューションがあるかもしれませんが、今ではdistribution = falseで始まり、sshを介してプロセスは起動しません。
答え2
私も同じ/似たような問題があります。 「myService」スクリプト内でsuまたはsudoを使用するとします。これにより、サービスプロセスはsystem.sliceの代わりにuser.sliceで開始されます。
明らかに、user.sliceで「重要な」何も実行しないでください。systemdはシャットダウン/再起動時にすべての(?)プロセスを終了します。
起動スクリプトからすべてのユーザースイッチ(su / sudo)を削除し、ユニットファイルのユーザーディレクティブ(User = xxx)を使用してこの問題を解決しました。
プロセスが実行されている場所(任意のスライス)を確認してください。systemd-cgls