[轉載]服務器管理模塊forever——Nodejs中間件系列

從零開始nodejs系列文章,將介紹如何利Javascript作爲服務端腳本,經過Nodejs框架web開發。Nodejs框架是基於V8的引擎,是目前速度最快的Javascript引擎。chrome瀏覽器就基於V8,同時打開20-30個網頁都很流暢。Nodejs標準的web開發框架Express,能夠幫助咱們迅速創建web站點,比起PHP的開發效率更高,並且學習曲線更低。很是適合小型網站,個性化網站,咱們本身的Geek網站!!javascript

關於做者html

  • 張丹(Conan), 程序員Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

轉載請註明出處:
http://blog.fens.me/nodejs-server-forever/java

nodejs-forever

目前node

又說到服務器管理了,上次說的時候用的是Linux系統服務upstart, 今天準備嘗試一下Nodejs本身模塊化解決方案forever。linux

服務器管理是系統上線後,必需要面對的問題。最好有一個軟件能夠提供整套的服務器運行解決方案:要求運行穩定,支持高併發,啓動/中止命令簡單,支持熱部署,宕機重啓,監控界面和日誌,集羣環境。程序員

接下來,就讓咱們看看forever能不能實現目標。web

前言chrome

  1. forever介紹
  2. forever安裝
  3. forever命令行的中文解釋
  4. forever服務器管理
  5. forever在Ubuntu進行服務器管理
  6. 模擬服務器宕機
  7. 開發環境和生產環境的啓動配置

1. forever介紹

forever是一個簡單的命令式nodejs的守護進程,可以啓動,中止,重啓App應用。forever徹底基於命令行操做,在forever進程之下,建立node的子進程,經過monitor監控node子進程的運行狀況,一旦文件更新,或者進程掛掉,forever會自動重啓node服務器,確保應用正常運行。express

2. forever安裝

全局安裝forevernpm

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

經過「Commander寫本身的Nodejs命令」一文的介紹,咱們已經知道如何看懂,並實現自定義的命令行了。雖然,forever不是基於Commander的,而是基於另外一個命令行開發包optimist,原理都是相似的。

因此,咱們看到forever支持的命令和配置項確實很多,應該是偏命令行的管理工具。

3. 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: 命令行幫助信息

4. 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繼續測試。

5. 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環境中是正常的。

6. 模擬服務器宕機

兩種測試方案:

  • 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)。其餘的功能,還要更近一步的使用才知道。

7. 開發環境和生產環境的啓動配置

開發環境

~ 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

轉載請註明出處:
http://blog.fens.me/nodejs-server-forever/

相關文章
相關標籤/搜索