Nodejs进程管理模块forever详解


Posted in NodeJs onJune 01, 2014

接下来,就让我们看看forever能不能实现目标。

一、forever介绍

forever是一个简单的命令式nodejs的守护进程,能够启动,停止,重启App应用。forever完全基于命令行操作,在forever进程之下,创建node的子进程,通过monitor监控node子进程的运行情况,一旦文件更新,或者进程挂掉,forever会自动重启node服务器,确保应用正常运行。

二、 forever安装

全局安装forever

~ D:\workspace\javascript>npm install -g forever
D:\toolkit\nodejs\forever -> D:\toolkit\nodejs\node_modules\forever\bin\forever
D:\toolkit\nodejs\foreverd -> D:\toolkit\nodejs\node_modules\forever\bin\foreverd

查看forever帮助
~ D:\workspace\javascript>forever -h
help: usage: forever [action] [options] SCRIPT [script-options]
help:
help: Monitors the script specified in the current process or as a daemon
help:
help: actions:
help: start Start SCRIPT as a daemon
help: stop Stop the daemon SCRIPT
help: stopall Stop all running forever scripts
help: restart Restart the daemon SCRIPT
help: restartall Restart all running forever scripts
help: list List all running forever scripts
help: config Lists all forever user configuration
help: set <key> <val> Sets the specified forever config <key>
help: clear <key> Clears the specified forever config <key>
help: logs Lists log files for all forever processes
help: logs <script|index> Tails the logs for <script|index>
help: columns add <col> Adds the specified column to the output in `forever list`
help: columns rm <col> Removed the specified column from the output in `forever list`
help: columns set <cols> Set all columns for the output in `forever list`
help: cleanlogs [CAREFUL] Deletes all historical forever log files
help:
help: options:
help: -m MAX Only run the specified script MAX times
help: -l LOGFILE Logs the forever output to LOGFILE
help: -o OUTFILE Logs stdout from child script to OUTFILE
help: -e ERRFILE Logs stderr from child script to ERRFILE
help: -p PATH Base path for all forever related files (pid files, etc.)
help: -c COMMAND COMMAND to execute (defaults to node)
help: -a, --append Append logs
help: -f, --fifo Stream logs to stdout
help: -n, --number Number of log lines to print
help: --pidFile The pid file
help: --sourceDir The source directory for which SCRIPT is relative to
help: --minUptime Minimum uptime (millis) for a script to not be considered "spinning"
help: --spinSleepTime Time to wait (millis) between launches of a spinning script.
help: --colors --no-colors will disable output coloring
help: --plain alias of --no-colors
help: -d, --debug Forces forever to log debug output
help: -v, --verbose Turns on the verbose messages from Forever
help: -s, --silent Run the child script silencing stdout and stderr
help: -w, --watch Watch for file changes
help: --watchDirectory Top-level directory to watch from
help: --watchIgnore To ignore pattern when watch is enabled (multiple option is allowed)
help: -h, --help You're staring at it
help:
help: [Long Running Process]
help: The forever process will continue to run outputting log messages to the console.
help: ex. forever -o out.log -e err.log my-script.js
help:
help: [Daemon]
help: The forever process will run as a daemon which will make the target process start
help: in the background. This is extremely useful for remote starting simple node.js scripts
help: without using nohup. It is recommended to run start with -o -l, & -e.
help: ex. forever start -l forever.log -o out.log -e err.log my-daemon.js
help: forever stop my-daemon.js
help:

我们看到forever支持的命令和配置项确实不少,应该是偏命令行的管理工具。

三、forever命令行的中文解释

子命令actions:

start:启动守护进程
stop:停止守护进程
stopall:停止所有的forever进程
restart:重启守护进程
restartall:重启所有的foever进程
list:列表显示forever进程
config:列出所有的用户配置项
set <key> <val>: 设置用户配置项
clear <key>: 清楚用户配置项
logs: 列出所有forever进程的日志
logs <script|index>: 显示最新的日志
columns add <col>: 自定义指标到forever list
columns rm <col>: 删除forever list的指标
columns set<cols>: 设置所有的指标到forever list
cleanlogs: 删除所有的forever历史日志

配置参数options:
-m MAX: 运行指定脚本的次数
-l LOGFILE: 输出日志到LOGFILE
-o OUTFILE: 输出控制台信息到OUTFILE
-e ERRFILE: 输出控制台错误在ERRFILE
-p PATH: 根目录
-c COMMAND: 执行命令,默认是node
-a, ?append: 合并日志
-f, ?fifo: 流式日志输出
-n, ?number: 日志打印行数
?pidFile: pid文件
?sourceDir: 源代码目录
?minUptime: 最小spinn更新时间(ms)
?spinSleepTime: 两次spin间隔时间
?colors: 控制台输出着色
?plain: ?no-colors的别名,控制台输出无色
-d, ?debug: debug模式
-v, ?verbose: 打印详细输出
-s, ?silent: 不打印日志和错误信息
-w, ?watch: 监控文件改变
?watchDirectory: 监控顶级目录
?watchIgnore: 通过模式匹配忽略监控
-h, ?help: 命令行帮助信息

四、forever服务器管理

创建一个web项目(express3+ejs),使用forever管理服务器。

安装express3

~ D:\workspace\javascript>express -e nodejs-forever
~ D:\workspace\javascript>cd nodejs-forever && npm install

通过forever启动应用
~ D:\workspace\javascript\nodejs-forever>forever start app.js
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: app.js

打开浏览器: http://localhost:3000,可以看到web界面

在win下面查看forever状态

~ D:\workspace\javascript\nodejs-forever>forever list
info:    No forever processes running
~ D:\workspace\javascript\nodejs-forever>forever stop app.js
error:   Forever cannot find process with index: app.js

我们发现forever的程序,工作不对了!!程序明明是运行状态,通过list确看不到。接下来,切换成Linux Ubuntu继续测试。

五、forever在Ubuntu进行服务器管理

Linux的系统环境

Linux: Ubuntu 12.04.2 64bit Server
Node: v0.11.2
Npm: 1.2.21
初始化项目:安装命令不解释了

~ cd /home/conan/nodejs
~ express -e nodejs-forever
~ cd nodejs-forever && npm install
~ sudo npm install forever -g

启动forever
~ forever start app.js
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: app.js

查看node服务器状态
~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile                       uptime
data:    [0] L2tY /usr/local/bin/node app.js 18276   18279 /home/conan/.forever/L2tY.log 0:0:0:37.792
# 系统进程
~ ps -aux|grep node
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
conan    18296  0.5  1.1 597696 23776 ?        Ssl  15:48   0:00 /usr/local/bin/node /usr/local/lib/node_modules/forever/bin/monitor app.js
conan    18299  0.4  0.8 630340 18392 ?        Sl   15:48   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
# 端口占用
~ netstat -nltp|grep node
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      18299/node

停止服务器

~ forever stop app.js
info:    Forever stopped process:
data:        uid  command             script forever pid   logfile                       uptime
[0] L2tY /usr/local/bin/node app.js 18276   18279 /home/conan/.forever/L2tY.log 0:0:0:45.621

我们看到在Linux Ubuntu环境中是正常的。

六、模拟服务器宕机

两种测试方案:

1. 用Linux命令,直接杀死node进程
2. 在应用中,模拟异常退出

1). 用Linux命令,直接杀死node进程

# 查看node进程,PID=18299  
~ ps -aux|grep node
conan    18296  0.0  1.1 597696 23776 ?        Ssl  15:48   0:00 /usr/local/bin/node /usr/local/lib/node_modules/forever/bin/monitor app.js
conan    18299  0.0  0.8 630340 18392 ?        Sl   15:48   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
conan    18315  0.0  0.0  13584   956 pts/5    R+   15:52   0:00 grep --color=auto node
# 杀死PID=19299
~ kill -9 18299
# 再看node进程,node自动重启,新的PID=18324  
~ ps -aux|grep node
conan    18296  0.0  1.1 597696 23916 ?        Ssl  15:48   0:00 /usr/local/bin/node /usr/local/lib/node_modules/forever/bin/monitor app.js
conan    18316  2.6  0.8 630340 18412 ?        Sl   15:52   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
conan    18324  0.0  0.0  13584   956 pts/5    R+   15:52   0:00 grep --color=auto node

我们看到看杀死node进程,forever会帮助我们,重启node。

杀死forever的monitor

~ kill -9  18296
~ ps -aux|grep node
conan    18316  0.0  0.9 630340 18644 ?        Sl   15:52   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
conan    18333  0.0  0.0  13584   952 pts/5    S+   15:57   0:00 grep --color=auto node
# 再杀死node进程
~ kill -9 18316
~ ps -aux|grep node
conan    18336  0.0  0.0  13584   956 pts/5    S+   15:58   0:00 grep --color=auto node

我们尝试杀死了forever的monitor,monitor程序没有自动重启,然后再杀死node进程后,node也不会自动重启了。

2). 在应用中,模拟异常退出
修改文件:app.js

~ vi app.js
//..
http.createServer(app).listen(app.get('port'), function(){
  console.log(new Date());
  console.log('Express server listening on port ' + app.get('port'));
});
setTimeout(function(){
  console.log(new Date());
  throw new Error('App is error from inner!');
},10*1000);

通过node命令启动
~ node app.js
Thu Sep 26 2013 16:08:44 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:08:54 GMT+0800 (CST)
/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

10秒后,由于内部错误, node进程挂掉了。

通过forever命令启动

~ mkdir logs
~ chmod 777 -R logs
~ forever -p . -l ./logs/access.log -e ./logs/error.log start app.js
# 检查错误日志
~ cat logs/access.log ls
Thu Sep 26 2013 16:15:02 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:12 GMT+0800 (CST)
/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 1 time
Thu Sep 26 2013 16:15:13 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:23 GMT+0800 (CST)
/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 2 time
Thu Sep 26 2013 16:15:23 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:33 GMT+0800 (CST)
/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 3 time
Thu Sep 26 2013 16:15:33 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:43 GMT+0800 (CST)
/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 4 time

我们发现每10秒种,node内部挂掉,然后再被forever重启!!

通过list我们手动刷新几次也可以看到pid是变的。

~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18579 logs/access.log 0:0:0:7.211
~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18579 logs/access.log 0:0:0:8.921
~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18604 logs/access.log 0:0:0:0.177
~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18604 logs/access.log 0:0:0:2.206

这样forever就帮助我们完成了,几项比较重要服务器管理功能:“启动/停止命令简单”,“支持热部署”,“宕机重启”,“监控界面和日志”。

比起upstart管理,省略了配置脚本的步骤(/etc/init/nodejs-xx.conf)。其他的功能,还要更近一步的使用才知道。

七、开发环境和生产环境的启动配置

开发环境

~ cd /home/conan/nodejs/nodejs-forever/
~ forever -p . -l ./logs/access.log -e ./logs/error.log -a -w start app.js

生产环境
~ export LOG=/var/log/nodejs/project
~ export PID=/var/log/nodejs/project/forever.pid
~ export APP_PATH=/home/conan/nodejs/nodejs-forever
~ export APP=$APP_PATH/app.js
~ forever -p $APP_PATH -l $LOG/access.log -e $LOG/error.log -o $LOG/out.log -a --pidFile $PID start $APP

NodeJs 相关文章推荐
nodejs开发环境配置与使用
Nov 17 NodeJs
nodejs教程之入门
Nov 21 NodeJs
搭建简单的nodejs http服务器详解
Mar 09 NodeJs
深入学习nodejs中的async模块的使用方法
Jul 12 NodeJs
详解使用vscode+es6写nodejs服务端调试配置
Sep 21 NodeJs
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
May 15 NodeJs
解决nodejs的npm命令无反应的问题
May 17 NodeJs
Nodejs实现用户注册功能
Apr 14 NodeJs
详解微信小程序-获取用户session_key,openid,unionid - 后端为nodejs
Apr 29 NodeJs
Nodejs文件上传、监听上传进度的代码
Mar 27 NodeJs
基于NodeJS开发钉钉回调接口实现AES-CBC加解密
Aug 20 NodeJs
详解NodeJS模块化
Jun 15 NodeJs
NodeJS Express框架中处理404页面一个方式
May 28 #NodeJs
跟我学Nodejs(三)--- Node.js模块
May 25 #NodeJs
跟我学Nodejs(二)--- Node.js事件模块
May 21 #NodeJs
跟我学Nodejs(一)--- Node.js简介及安装开发环境
May 20 #NodeJs
Nodejs使用mysql模块之获得更新和删除影响的行数的方法
Mar 18 #NodeJs
用nodejs实现PHP的print_r函数代码
Mar 14 #NodeJs
nodejs读取memcache示例分享
Jan 02 #NodeJs
You might like
8个出色的WordPress SEO插件收集
2011/02/26 PHP
PHP设计模式之简单工厂和工厂模式实例分析
2019/03/25 PHP
去除链接虚线全面分析总结
2006/08/15 Javascript
得到文本框选中的文字,动态插入文字的js代码
2007/03/07 Javascript
jquery下异步提交表单 异步跨域提交表单
2010/11/17 Javascript
javascript学习笔记(十) js对象 继承
2012/06/19 Javascript
究竟什么是Node.js?Node.js有什么好处?
2015/05/29 Javascript
简介JavaScript中Math.cos()余弦方法的使用
2015/06/15 Javascript
详解参数传递四种形式
2015/07/21 Javascript
Jquery 1.9.1源码分析系列(十二)之筛选操作
2015/12/02 Javascript
JQuery中Ajax()的data参数类型实例分析
2015/12/15 Javascript
Angular实现跨域(搜索框的下拉列表)
2017/02/16 Javascript
微信小程序之页面拦截器的示例代码
2017/09/07 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
2017/12/25 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
2018/07/26 Javascript
jQuery轻量级表单模型验证插件
2018/10/15 jQuery
jQuery实现视频展示效果
2020/05/30 jQuery
[56:56]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
Tornado Web服务器多进程启动的2个方法
2014/08/04 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
通过Py2exe将自己的python程序打包成.exe/.app的方法
2018/05/26 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
2018/10/21 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
移动端解决悬浮层(悬浮header、footer)会遮挡住内容的3种方法
2015/03/27 HTML / CSS
美国最大点评网站:Yelp
2018/02/14 全球购物
JNI的定义
2012/11/25 面试题
工商管理实习自我鉴定
2013/09/28 职场文书
音乐教学案例
2014/01/30 职场文书
公司员工检讨书
2014/02/08 职场文书
cf战队收人口号
2014/06/21 职场文书
旷课检讨书500字
2014/10/14 职场文书
先进教育工作者事迹材料
2014/12/23 职场文书
毕业实习指导教师评语
2014/12/31 职场文书
新郎结婚保证书
2015/02/26 职场文书
python树莓派通过队列实现进程交互的程序分析
2021/07/04 Python
Go gRPC进阶教程gRPC转换HTTP
2022/06/16 Golang