服务器管理是系统上线后,必须要面对的问题。最好有一个软件可以提供整套的服务器运行解决方案:要求运行稳定,支持高并发,启动/停止命令简单,支持热部署,宕机重启,监控界面和日志,集群环境。

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

一、forever介绍

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

二、 forever安装

全局安装forever


~ D:workspacejavascript>npm install -g forever
D:toolkitnodejsforever -> D:toolkitnodejsnode_modulesforeverbinforever
D:toolkitnodejsforeverd -> D:toolkitnodejsnode_modulesforeverbinforeverd

查看forever帮助

~ D:workspacejavascript>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:workspacejavascript>express -e nodejs-forever
~ D:workspacejavascript>cd nodejs-forever && npm install

通过forever启动应用

~ D:workspacejavascriptnodejs-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:workspacejavascriptnodejs-forever>forever list
info:  No forever processes running

~ D:workspacejavascriptnodejs-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


最新资讯
亚马逊创始人杰夫·贝索斯前妻成为美国最富有女性

亚马逊创始人杰夫·贝

福布斯11日宣布,亚马逊创始人杰夫·贝索斯的前妻麦肯齐
累计融资超20亿美元 理想汽车吹响市值千亿美元冲锋号?

累计融资超20亿美元

继蔚来之后,理想汽车有望成为第二家登陆资本市场的造车
美团5亿美元加持理想汽车:成第二大股东 持股14.5%

美团5亿美元加持理想

理想汽车昨日向SEC递交招股书,股票代码为“LI”,准备冲
北京SKP:餐品会送至指定位置 外卖员由员工通道进入

北京SKP:餐品会送至指

针对日前博主爆料”北京SKP不允许外卖员进入“一事,今
王兴急着变现,李想心急求钱

王兴急着变现,李想心急

李想,曾经的汽车之家创始人,现在的理想汽车(原“车和家”
SpaceX再次推迟星链和BlackSky卫星发射

SpaceX再次推迟星链和

当地时间7月11日,SpaceX再次推迟了最新的星链卫星发射,
最新文章
Vue实现图片与文字混输效果

Vue实现图片与文字混

用多了 JQuery ,习惯了使用JQuery的API操作 DOM ,几乎忘
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)

Vue实现点击当前元素

这篇文章主要介绍了Vue实现点击当前元素以外的地方隐
Vue实现验证码功能

Vue实现验证码功能

这篇文章主要为大家详细介绍了Vue实现验证码功能,文中
JS实现的雪花飘落特效示例

JS实现的雪花飘落特效

这篇文章主要介绍了JS实现的雪花飘落特效,结合实例形
微信小程序实现图片压缩

微信小程序实现图片压

这篇文章主要为大家详细介绍了微信小程序实现图片压缩
JavaScript实现京东放大镜效果

JavaScript实现京东放

这篇文章主要为大家详细介绍了JavaScript实现京东放大