如何确保应用程序在Linux上继续运行
我试图确保一个脚本仍然在开发服务器上运行。 它整理统计信息,并提供一个Web服务,所以它应该坚持下去,但每天几次,它会因不明原因而死亡。 当我们注意到我们只是再次启动它,但这是一个痛苦的后方,一些用户没有权限(或知识)启动它。
我的程序员想要花费几个小时才能到达问题的底部,但是我身边的忙碌者认为必须有一个简单的方法来检测应用程序是否没有运行,然后再次启动。
我知道我可以 cron脚本ps通过grep:
ps -A | grep appname
但是再一次的,这又是我生命中的另一个小时,浪费了一些必须已经存在的东西…是不是有一个预制的应用程序,我可以通过一个可执行文件(可选的参数),并将保持一个进程无限期地运行?
如果它有什么区别,那就是Ubuntu。
由于您使用的是Ubuntu,您可能对Upstart感兴趣,它已经取代了传统的sysV init 。 其中一个关键特性是,如果意外死亡,它可以重新启动服务。 Fedora已经变成了新贵,而Debian正处于试验阶段,因此可能值得研究。
虽然这可能是矫枉过正的,因为cron脚本需要2分钟才能实现。
#!/bin/bash if [[ ! `pidof -s yourapp` ]]; then invoke-rc.d yourapp start fi
我用一个简单的脚本与cron来确保程序正在运行。 如果不是,那么它会启动它。 这可能不是您正在寻找的完美解决scheme,但它很简单,工作得很好。
#!/bin/bash #make-run.sh #make sure a process is always running. export DISPLAY=:0 #needed if you are running a simple gui app. process=YourProcessName makerun="/usr/bin/program" if ps ax | grep -v grep | grep $process > /dev/null then exit else $makerun & fi exit
然后每分钟或每5分钟添加一个cron作业。
Monit是完美的:)
你可以写简单的configuration文件告诉监视,如TCP端口,PID文件等
monit将运行你指定的命令,当它正在监视的进程不可用时/使用太多的内存/正在盯住CPU太长时间/ etc。 它也会popup一个电子邮件警报,告诉你发生了什么事,是否可以做任何事情。
我们使用它来保持我们网站的运行,同时在出现问题时给予我们预警。
– 你忠实的员工Monit
如果您使用的是基于systemd的发行版(如Fedora和最新的Ubuntu发行版),则可以使用systemd的“重新启动”function进行服务。 它可以设置为系统服务或用户服务,如果它需要由特定用户来pipe理和运行的话,在OP的特殊情况下更可能是这种情况。
“重新启动”选项采用“ on-success
, on-failure
, on-abnormal
, on-watchdog
, on-abort
或always
。
要以用户身份运行它,只需将如下所示的文件放入~/.config/systemd/user/something.service
:
[Unit] Description=Something [Service] ExecStart=/path/to/something Restart=on-failure [Install] WantedBy=graphical.target
然后:
systemctl --user daemon-reload systemctl --user [status|start|stop|restart] something
没有root权限/系统文件修改需要,不需要cron作业,没有安装,灵活的地狱(见文档中的所有相关的服务选项)。
有关使用每用户systemd实例的更多信息,另请参阅https://wiki.archlinux.org/index.php/Systemd/User 。
把你的运行放在一个循环中 – 所以当它退出时,它会再次运行… while(true){run my app ..}
我用cron“killall -0 programname || /etc/init.d/programname start”。 如果进程不存在,kill会报错。 如果它确实存在,它会向进程发送一个空信号(内核将忽略这个信号,而不会继续传递)。
这个成语很容易记住(恕我直言)。 通常我使用这个,而我仍然试图发现为什么服务本身是失败的。 恕我直言,一个程序不应该只是消失意外:)
首先,你如何开始这个应用程序? 它是否自己背景? 它是否以nohup开始..&等? 如果是后者,请检查它为什么在nohup.out中死亡,如果是第一个,则build立日志logging。
至于你的主要问题:你可以cron它,或者在后台运行另一个进程(而不是最好的select),并使用pidof在一个bash脚本中,很简单:
if [ `pidof -s app` -eq 0 ]; then nohup app & fi
你可以使它成为一个从inittab启动的服务(尽pipe有些Linux已经转向了/etc/event.d中更新的东西)。 这些内置的系统可以确保您的服务在不编写自己的脚本或安装新内容的情况下继续运行。
这是一个DMD(守护进程监控守护进程)的工作。 周围有几个; 但是我通常只是写一个脚本来检查守护进程是否正在运行,如果没有运行,就把它放在cron中,每分钟运行一次。
查阅“Unix Hater's Handbook”第9章(p197或其附件)中引用的“ nanny
” (PDF格式的书籍的几个来源之一)。
一个很好的,简单的方法来做到这一点如下:
- 如果服务器不能监听它期望的端口,就把它写下来
- 设置一个cronjob来尝试每分钟启动你的服务器
如果它没有运行,它会开始,如果它正在运行,它不会。 无论如何,你的服务器将会一直运行。
daemontools
的supervise
工具将是我的首选 – 但是然后丹J伯恩斯坦写的是我的首选:)
http://cr.yp.to/daemontools/supervise.html
您必须为应用程序启动脚本创build特定的目录结构,但使用起来非常简单。
Chris Wendt的解决scheme由于某种原因无法工作,而且很难debugging。 这一个是几乎相同,但更容易debugging,从模式匹配排除bash。 要debugging运行: bash ./root/makerun-mysql.sh
。 在下面的例子中,mysql-server只是replaceprocess
和process
variables的值。
- 像这样创build一个BASH脚本(
nano /root/makerun-mysql.sh
):
#!/bin/bash process="mysql" makerun="/etc/init.d/mysql restart" if ps ax | grep -v grep | grep -v bash | grep --quiet $process then printf "Process '%s' is running.\n" "$process" exit else printf "Starting process '%s' with command '%s'.\n" "$process" "$makerun" $makerun fi exit
-
通过添加适当的文件权限(例如
chmod 700 /root/makerun-mysql.sh
)确保它是可执行的 -
然后将其添加到您的crontab(
crontab -e
):
# Keep processes running every 5 minutes */5 * * * * bash /root/makerun-mysql.sh
我认为更好的解决scheme是,如果你testing的function也一样。 例如,如果你必须testing一个apache,如果系统上存在“apache”进程,仅仅testing是不够的。
如果你想testing一下apache是否正确,那么试着下载一个简单的网页,并testing你的唯一代码是否在输出中。
如果没有,用-9杀死Apache,然后重启。 并发送邮件到根(这是一个转发的邮件地址的公司/服务器/项目的根)。
它甚至更简单:
#!/bin/bash export DISPLAY=:0 process=processname makerun="/usr/bin/processname" if ! pgrep $process > /dev/null then $makerun & fi
你必须记住,虽然确保过程名是唯一的。