当服务器关闭/崩溃时,Node JS 会自动重启所有永远的 JS 进程

Posted

技术标签:

【中文标题】当服务器关闭/崩溃时,Node JS 会自动重启所有永远的 JS 进程【英文标题】:Node JS auto restart all forever JS process when server goes down / crashes 【发布时间】:2016-09-08 21:20:13 【问题描述】:

我正在使用 forever js 来保持我的节点服务器在 AWS EC2 上 24/7 全天候运行。

我用这个命令

forever start index.js

但是,我注意到有时它会随机停止该过程并且我的网站出现故障。我必须手动 ssh 到我的服务器才能再次运行它:

forever restartall

然后它会进行备份。有什么方法可以定义超时,假设服务器/网站在 5 秒内没有响应 200 秒,然后自动重新启动所有永久进程?

我是新手,如果有人可以为我的案例提供逐步的示例,那就太棒了。

【问题讨论】:

如果这是一台 *NIX 机器,那么您可以简单地定义一个在 cron 作业上运行的 shell 脚本来检查进程的状态并在必要时重新启动。 Automatically start forever (node) on system restart的可能重复 @EvanBechtol 它在 AWS EC2 t2.micro linux ubuntu 上。我对此完全陌生,您能否提供代码示例如何以及在何处定义和运行 shell 脚本?谢谢,我会把它标记为最佳答案:) @Fizan 当然,我今天会发布一个示例。抱歉耽搁了 检查已经存在的答案***.com/questions/13385029/… 【参考方案1】:

我建议使用PM2

这是在生产服务器上运行的最佳选择。

以这种方式运行您的应用程序有什么优势?

易于设置和运行。 如果您的应用程序崩溃,PM2 会自动重启。 PM2 将记录您未处理的异常 - 在这种情况下,在 /home/safeuser/.pm2/logs/app-err.log 的文件中。 通过一个命令,PM2 可以确保它管理的任何应用程序在服务器重新启动时重新启动。基本上意味着您的节点应用程序将作为服务启动。

参考:https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

【讨论】:

【参考方案2】:

(NodeJS)服务器不应无缘无故停止。大多数情况下,这是因为没有catched 的 500 错误并停止服务器,然后您将不得不重新启动它。 forever 默认使用node 来启动你的服务器。

nodemon 是一个 npm 包,可在代码更改或服务器停止时重新启动服务器。

您可以通过以下方式同时使用forevernodemon

forever start nodemon --exitcrash app.js

forever start -c nodemon app.js

或者,正如其他答案中所建议的,您可以使用PM2,这对生产会更好!

【讨论】:

Forever 现在似乎包含了观看。使用'forever -o out.log -e err.log -w app.js'【参考方案3】:

所以这是一个使用cron运行脚本的例子,这些脚本可以重新启动服务/执行一些自动化任务。基本上,我创建了一些我需要在我的服务器上以特定时间间隔运行的脚本。对于您的情况,您想要创建一个脚本,该脚本将自动检查您的 forever.js 的状态,如果它返回错误的响应,请运行您上面提到的 forever restartall 命令。

您可以在服务器上通过creating a new crontab entry 进行设置。就脚本而言,我绝不是 bash 脚本专家。我制作了一个适合我的简单脚本。这是一个检查我机器上的服务的示例,如果它没有运行则重新启动它。

#!/bin/bash
zabbix_server="service zabbix-server"
zabbix_agent="service zabbix-agent"
logfile=zabbix_auto_restart.log
logfilePath=/etc/scripts/zabbix/$logfile
zabbix_server_running=0
zabbix_agent_running=0

grep_agent ()
        local retval=$(ps -ef | grep -v grep | grep zabbix_agentd | wc -l)
        echo $retval


grep_server ()
        local retval=$(ps -ef | grep -v grep | grep zabbix_server | wc -l)
        echo $retval


check_zabbix_agentd ()
        if (( $(grep_agent) <= 0 ))
        then
           sudo /etc/init.d/zabbix-agent start
           echo `date` "$zabbix_agent was stopped... Restarting" >> $logfilePath
           echo "************************************************" >> $logfilePath

           #Send email to notify that the script ran
           echo "$(date) $zabbix_agent was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <my-email>

        else
           let zabbix_agent_running=1
        fi


check_zabbix_server ()
        if (( $(grep_server) <= 0 ))
        then
           sudo /etc/init.d/zabbix-server start
           echo `date` "$zabbix_server was stopped... Restarting" >> $logfilePath
           echo "************************************************" >> $logfilePath

           #Send email to notify that the script ran
           echo "$(date) $zabbix_server was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" evan.bechtol@ericsson.com

        else
           let zabbix_server_running=1
        fi


main_loop ()
        until ((zabbix_server_running == 1 && zabbix_agent_running == 1));
        do
                check_zabbix_agentd
                check_zabbix_server
                sleep 1.5
        done


main_loop

【讨论】:

【参考方案4】:

您是否考虑过 pm2 作为替代方案。 pm2 有一些非常简洁的功能,例如:

运行集群 一一重启集群中的实例(零停机部署) 资源监控(显示实时 CPU 和内存使用情况) 使用 cli 管理所有 pm2 进程

您也可以通过添加--restart-delay &lt;delay&gt; 选项来控制重启。

特此提供此工具帮助的完整输出。

pm2 --help

                    -------------
Looking for a complete monitoring and management tool for PM2?
 _                             _        _            _
| | _____ _   _ _ __ ___   ___| |_ _ __(_) ___ ___  (_) ___
| |/ / _ \ | | | '_ ` _ \ / _ \ __| '__| |/ __/ __| | |/ _ \
|   <  __/ |_| | | | | | |  __/ |_| |  | | (__\__ \_| | (_) |
|_|\_\___|\__, |_| |_| |_|\___|\__|_|  |_|\___|___(_)_|\___/
     |___/

                      Features

               - Real Time Dashboard
               - CPU/Memory monitoring
               - HTTP monitoring
               - Event notification
               - Custom value monitoring
               - Real Time log display

                      Checkout

               https://keymetrics.io/

                    -------------

[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized

Usage: pm2 [cmd] app

Commands:

start [options] <file|json|stdin|app_name|pm_id...>                  start and daemonize an app
deploy <file|environment>                                            deploy your json
startOrRestart <json>                                                start or restart JSON file
startOrReload <json>                                                 start or gracefully reload JSON file
startOrGracefulReload <json>                                         start or gracefully reload JSON file
stop [options] <id|name|all|json|stdin...>                           stop a process (to start it again, do pm2 restart <app>)
restart [options] <id|name|all|json|stdin...>                        restart a process
scale <app_name> <number>                                            scale up/down a process in cluster mode depending on total_number param
reload <name|all>                                                    reload processes (note that its for app using HTTP/HTTPS)
gracefulReload <name|all>                                            gracefully reload a process. Send a "shutdown" message to close all connections.
id <name>                                                            get process id by name
delete <name|id|script|all|json|stdin...>                            stop and delete a process from pm2 process list
sendSignal <signal> <pm2_id|name>                                    send a system signal to the target process
ping                                                                 ping pm2 daemon - if not up it will launch it
updatePM2                                                            update in-memory PM2 with local PM2
update                                                               (alias) update in-memory PM2 with local PM2
install|module:install <module|git:/>                                install or update a module and run it forever
module:update <module|git:/>                                         update a module and run it forever
module:generate [app_name]                                           Generate a sample module in current folder
uninstall|module:uninstall <module>                                  stop and uninstall a module
publish|module:publish                                               Publish the module you are currently on
set <key> <value>                                                    sets the specified config <key> <value>
multiset <value>                                                     multiset eg "key1 val1 key2 val2
get [key]                                                            get value for <key>
conf [key] [value]                                                   get / set module config values
config <key> [value]                                                 get / set module config values
unset <key>                                                          clears the specified config <key>
interact [options] [secret_key|command] [public_key] [machine_name]  linking action to keymetrics.io - command can be stop|info|delete|restart
link [options] [secret_key|command] [public_key] [machine_name]      linking action to keymetrics.io - command can be stop|info|delete|restart
web                                                                  launch a health API on port 9615
dump                                                                 dump all processes for resurrecting them later
save                                                                 (alias) dump all processes for resurrecting them later
resurrect                                                            resurrect previously dumped processes
startup [platform]                                                   auto resurrect process at startup. [platform] = ubuntu, centos, redhat, gentoo, systemd, darwin, amazon
logrotate                                                            copy default logrotate configuration
generate                                                             generate an ecosystem.json configuration file
ecosystem                                                            generate an ecosystem.json configuration file
reset <name|id|all>                                                  reset counters for process
describe <id>                                                        describe all parameters of a process id
desc <id>                                                            (alias) describe all parameters of a process id
info <id>                                                            (alias) describe all parameters of a process id
show <id>                                                            (alias) describe all parameters of a process id
list                                                                 list all processes
ls                                                                   (alias) list all processes
l                                                                    (alias) list all processes
status                                                               (alias) list all processes
jlist                                                                list all processes in JSON format
prettylist                                                           print json in a prettified JSON
monit                                                                launch termcaps monitoring
m                                                                    (alias) launch termcaps monitoring
flush                                                                flush logs
reloadLogs                                                           reload all logs
logs [options] [id|name]                                             stream logs file. Default stream all logs
kill                                                                 kill daemon
pull <name> [commit_id]                                              updates repository for a given app
forward <name>                                                       updates repository to the next commit for a given app
backward <name>                                                      downgrades repository to the previous commit for a given app
gc                                                                   force PM2 to trigger garbage collection
deepUpdate                                                           performs a deep update of PM2
*

Options:

-h, --help                           output usage information
-V, --version                        output the version number
-v --version                         get version
-s --silent                          hide all messages
-m --mini-list                       display a compacted list without formatting
-f --force                           force actions
-n --name <name>                     set a <name> for script
-i --instances <number>              launch [number] instances (for networked app)(load balanced)
-l --log [path]                      specify entire log file (error and out are both included)
-o --output <path>                   specify out log file
-e --error <path>                    specify error log file
-p --pid <pid>                       specify pid file
-k --kill-timeout <delay>            delay before sending final SIGKILL signal to process
--max-memory-restart <memory>        specify max memory amount used to autorestart (in megaoctets)
--restart-delay <delay>              specify a delay between restarts (in milliseconds)
--env <environment_name>             specify environment to get specific env variables (for JSON declaration)
-x --execute-command                 execute a program using fork system
-u --user <username>                 define user when generating startup script
--hp <home path>                     define home path when generating startup script
-c --cron <cron_pattern>             restart a running process based on a cron pattern
-w --write                           write configuration in local folder
--interpreter <interpreter>          the interpreter pm2 should use for executing app (bash, python...)
--interpreter-args <arguments>       interpret options (alias of --node-args)
--log-date-format <momentjs format>  add custom prefix timestamp to logs
--no-daemon                          run pm2 daemon in the foreground if it doesn't exist already
--skip-env                           do not refresh environmnent on restart/reload
--source-map-support                 force source map support
--only <application-name>            with json declaration, allow to only act on one application
--disable-source-map-support         force source map support
--merge-logs                         merge logs from different instances but keep error and out separated
--watch [paths]                      watch application folder for changes
--ignore-watch <folders|files>       folder/files to be ignored watching, chould be a specific name or regex - e.g. --ignore-watch="test node_modules "some scripts""
--node-args <node_args>              space delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"
--no-color                           skip colors
--no-vizion                          start an app without vizion feature (versioning control)
--no-autorestart                     start an app without automatic restart
--no-treekill                        Only kill the main process, not detached children
--no-pmx                             start an app without pmx
--no-automation                      start an app without pmx

Basic Examples:

Start an app using all CPUs available + set a name :
$ pm2 start app.js -i 0 --name "api"

Restart the previous app launched, by name :
$ pm2 restart api

Stop the app :
$ pm2 stop api

Restart the app that is stopped :
$ pm2 restart api

Remove the app from the process list :
$ pm2 delete api

Kill daemon pm2 :
$ pm2 kill

Update pm2 :
$ npm install pm2@latest -g ; pm2 update

More examples in https://github.com/Unitech/pm2#usagefeatures

Deployment help:

$ pm2 deploy help

【讨论】:

在早些时候调查此问题时,我读到了有关永远存在的几个问题。 PM2 是我的选择,尽管使用了几个月,但我没有任何理由抱怨。【参考方案5】:

想通了。问题是由于我的 EC2 实例中可用的 RAM 较少。我将 RAM 升级到 2 GB,到目前为止还没有遇到过崩溃。

节点也可以产生未捕获的异常错误,但我的主要问题是由于内存不足。

希望这对其他人有所帮助。

【讨论】:

虽然这是您问题的答案,但它并不是问题的真正答案。将来您可能会再次遇到这个问题,因为负载更大,而垂直扩展通常不是答案。 您真的应该按照我上面的回答检查 pm2。您可以使用pm2 monit &lt;yourapplication&gt; 随时查看实时内存使用情况 同时检查 pm2 选项,如果进程使用了​​某些内存,则通过在进程中自动重启来防止内存泄漏问题。 --max-memory-restart【参考方案6】:

这个视频是一个很棒的节点部署系列的一部分,最终在 UNIX 服务器上使用了一项服务......也许它可以帮助你。顺便说一句,这四个视频都值得一看…… Youtube-Link

【讨论】:

以上是关于当服务器关闭/崩溃时,Node JS 会自动重启所有永远的 JS 进程的主要内容,如果未能解决你的问题,请参考以下文章

nodemon:让node自动重启

node-dev使用简介

AWS EB 实例崩溃时是不是会自动重启?

安卓service关闭后怎么自动重启

Node.js热部署代码,实现修改代码后自动重启服务方便实时调试

Node.js 由 mysql 自动崩溃,其中没有任何操作