如果Linux后台进程失败,如何自动重启?


32

我有一个由init.d脚本在后台执行的进程。例如:

case "$1" in 
    start)
       /bin/myprocess &
    stop)
       killall myprocess
    restart)
       killall myprocess
       /bin/myprocess &
esac

在某些情况下,myprocess可能失败并返回。有什么(标准)方法可以检测到它的故障并自动重新启动?


可以,但是根据分配情况而有所不同。他们几乎都提供某种服务管理器。
大卫·史瓦兹

没有标准发行版,而是buildroot。所以我必须手动做...
Honza

Answers:


14

最简单的方法是将其添加到/ etc / inittab中,该文件旨在执行以下操作:

重新生成 如果该进程不存在,请启动该进程。不要等待其终止(继续扫描/ etc / inittab文件)。死后重新启动该进程。如果该进程存在,则不执行任何操作,然后继续扫描/ etc / inittab文件。

例如,您可以这样做:

# Run my stuff
myprocess:2345:respawn:/bin/myprocess

请注意,/etc/inittab仅当您具有基于sysvinit的初始化系统时,该方法才有效(甚至存在)。对于暴发户和systemd,事实并非如此。您必须安装busybox(非常原始的shell会使sysadm进行繁琐的恢复任务,但是可以替换sysvinit兼容的initd)或sysvinit(这是化石)。在Docker容器中,只有第一个容器不会感到痛苦。
彼得说恢复莫妮卡

27

Buildroot有三种可能的初始化系统,因此可以通过三种方式进行:

忙箱 init

这样,您就可以在中添加一个条目/etc/inittab

::respawn:/bin/myprocess

请注意,BusyBox init具有特有的/etc/inittab格式。第二个字段没有意义,第一个字段不是ID,而是设备的基本名称。

Linux“系统V” init

再次,将一个条目添加到中/etc/inittab

myprocess:2345:respawn:/bin/myprocess

systemd

例如,有人将单位文件写入/etc/systemd/system/myprocess.service

[Unit]
Description=My Process

[Service]
ExecStart=/bin/myprocess
Restart=always

[Install]
WantedBy=multi-user.target

启用此选项可在启动时使用以下命令自动启动:

systemctl enable myprocess.service

手动启动它:

systemctl start myprocess.service

进一步阅读


但是当您使用inittab这种方法时,您的流程将不再可以通过“服务”界面访问,对吗?即你不能去service mything startservice mything stop不再....是有办法有两个最好的?即不可崩溃的sysvinit服务,但也可以通过“服务”使用它吗?
horseyguy

25

使用循环不断调用同一进程的子外壳怎么办?

如果结束,则循环的下一个迭代将继续并重新启动。

(while true; do 
    /bin/myprocess
done) &

如果子外壳死了,那就结束了。在这种情况下,唯一的可能性是创建另一个进程(我将其称为死灵法师),以检查您的进程是否处于活动状态,如果不是,则启动它,然后使用cron运行此死灵法师,以便您可以定期进行检查。

下一步将是想知道如果cron死了会发生什么,但是在某些时候您应该感到安全并且不再担心。


3

您可以使用Monit。它真的很容易使用并且非常灵活。请参阅此配置示例,以在失败时重新启动Tomcat进程。

check process tomcat with pidfile /var/run/tomcat.pid
   start program = "/etc/init.d/tomcat start"
   stop  program = "/etc/init.d/tomcat stop"
   if failed port 8080 type tcp then restart

对于许多用例,它也有很多配置示例


1

如果您不是超级用户或超级用户,并且您的Linux系统安装了Docker,则可以创建进程的docker映像,如果重新启动系统,则可以使用docker来重新启动进程。

档案:docker-compose.yml

version: "3"
services:
  lserver:
    image: your_docker_image:latest
    ports:
    - 8080:8080   # just use 8080 as an example
    restart: always  # this is where your process can be guaranteed to restart

要启动您的Docker容器,

docker-compose up -d

如果我不是系统的超级用户,我发现通过自动重启来处理我自己的进程很容易。

有关如何创建docker映像的示例示例,这是一个简单的示例:

文件:Dockerfile

FROM alpine:3.5

RUN apk update && apk upgrade && rm -rf /var/cache/apk/*
WORKDIR /app
COPY my-process-server /app
RUN ln -s /app/my-process-server /usr/local/bin/my-process-server

EXPOSE 8080

CMD ["my-process-server"]

0

就我而言,作为一种快速解决方案,我修改并使用了@Trylks的解决方案来包装正在启动的程序。我希望它只在干净的出口结束。

应该在大多数shell中运行:

#!/bin/sh

echo ""
echo "Use: $0 ./program"
echo ""

#eg="/usr/bin/apt update"

echo "Executing $1 ..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done) &

0

您可以使用重新启动器

start)
   restarter -c /bin/myprocess &
stop)
   pkill -f myprocess

在较新的系统上,使用systemd解决所有这些琐碎的问题

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.