2013-10-31

如何讓Node Express開發的Web Application可於開機後自動啟動

使用 Node.JS 及 Express 開發的 Web Application,因為底層沒有如 Apache 的 Web Server,所以,基本上,無法滿足「作業系統完成開機後,便自動啟動」的需求。

這下麻煩可大了,我們這個自動啟動的需求,該如何滿足?

還好,在 Linux 的世界,有個名為:「supervisor」的工具軟體。這套軟體的用途為:提供使用者,可對 UNIX-like 作業系統上執行的程式(processes),進行監視及控管。

透過這套工具,能讓我們將開發好的 Web Application,當成作業系統的服務(System Service)來用;而「作業系統的服務」因為可設成開機後自動啟動,所以,以上所述的需求,自然就能滿足了。

以下的安裝、設定程序,系以下列所示之環境為前題,因此,讀者在使用的時候,可能無法照著全抄,得需配合個人的環境,進行調整。
  • Node執行檔安裝之目錄路徑: /usr/bin/local/node 
  • Express Web Application的安裝路徑: /web/todos/app.js 
  • Express Web Log檔存放路徑:/web/logs 

執行程序

(1)安裝supervisor套件。
$ sudo easy_install supervisor

(2)透過指令產生「設定檔」。
$ sudo echo_supervisord_conf > /etc/supervisord.conf

(3)編輯設定檔,加入Node.JS Web App。
$ sudo vim /etc/supervisord.conf
在檔案的最底端,添加如下內容:
[program:myWebApp]
command=/usr/local/bin/node app.js
directory=/web/todos
autostart=true
autorestart=unexpected
startsecs=2
startretries=3
exitcodes=0,2
stdout_logfile=/web/logs/myWebApp.log
  • program之後的名稱:myWebApp非強制性的規範,可由個人自行決定。
  • Express Web的主程式app.js檔,其存放目錄路徑為「/web/todos」,但在「command」欄位,沒有標示出app.js檔案所在目錄路徑;反而標明在「directory」欄位中,這點須請留心。
  • 以上設定檔的「directory」、「stdout_logfile」、「command」欄位,很可能跟讀者的環境不同,請依個人需求自行修改。

(4)在路徑為:「/etc/rc.d/init.d」的目錄下,建立名為「supervisord.sh」的bash指令稿檔案。
$ sudo vim /etc/rc.d/init.d/supervisord.sh
完成編輯後,bash指令稿檔案的內容:
#!/bin/sh
#
# /etc/rc.d/init.d/supervisord
#
# Supervisor is a client/server system that
# allows its users to monitor and control a
# number of processes on UNIX-like operating
# systems.
#
# chkconfig: - 64 36
# description: Supervisor Server
# processname: supervisord

# Source init functions
. /etc/rc.d/init.d/functions

prog="supervisord"

prefix="/usr/"
exec_prefix="${prefix}"
prog_bin="${exec_prefix}/bin/supervisord"
PIDFILE="/var/run/$prog.pid"

start()
{
  echo -n $"Starting $prog: "
  daemon $prog_bin --pidfile $PIDFILE
  [ -f $PIDFILE ] && success $"$prog startup" || failure $"$prog startup"
  echo
}

stop()
{
  echo -n $"Shutting down $prog: "
  [ -f $PIDFILE ] && killproc $prog || success $"$prog shutdown"
  echo
}

case "$1" in

  start)
    start
    ;;

  stop)
    stop
    ;;

  status)
    status $prog
    ;;

  restart)
    stop
    start
    ;;

  *)
    echo "Usage: $0 {start|stop|restart|status}"
    ;;

esac

(5)設定supervisord.sh,使能開機後,自動執行。

5-1) 變更 supervisord.sh 檔案權限,使其可「執行」。
$ sudo chmod +x /etc/rc.d/init.d/supervisord.sh
5-2) 確認 supervisord.sh 檔案己具備可執行之權限。
$ ls -al /etc/rc.d/init.d/supervisord.sh
-rwxr-xr-x 1 root root 993 2013-10-31 07:38 /etc/rc.d/init.d/supervisord.sh
5-3) 查詢 supervisord.sh 檔案,在「作業系統服務 (System Service)」的「操作環境級別(Run Level)」。不過,以下的指令,最主要的目的,是要透過無法正常執行的結果,來證實 supervisord.sh 尚未完成註冊動作,所以無法查詢其「操作環境級別」,只會獲得錯誤訊息。
$ chkconfig --list supervisord.sh
supervisord.sh 服務支援 chkconfig,但未向任何執行等級註冊(請執行 'chkconfig --add supervisord.sh')
5-4) 將 supervisord.sh 註冊成作業系統的「服務」。
$ sudo chkconfig --add supervisord.sh
5-5) 設定 supervisord.sh 服務的操作環境級別,使之可以在作業系統完成開機後,便能自動啟動。
$ sudo chkconfig supervisord.sh on
5-6) 查詢 supervisord.sh 檔案,在作業系統「服務」中的「操作環境級別」(2,3,4,5)。
$ chkconfig --list supervisord.sh
supervisord.sh 0:關閉 1:關閉 2:開啟 3:開啟 4:開啟 5:開啟 6:關閉
完成以上設定工作後,請重開機。於確定重開機完成後,請找台 Web Client 端的電腦,打開 Web 瀏覽器,輸入網址,確認是否能連上你的 Web Application ,以便驗證此文所述之需求己經達成。

關於 Supervisor 的網路參考文章:

2013-10-30

如何在Mac建CA及核發伺服器憑證

想要讓Web伺服器能使用HTTPS通信協定,則Web Server務必需要有伺服器憑證。

可是,我們是「有窮氏」,沒$請具公信力的憑證發放中心(CA)核發。怎麼辦?

好吧!窮則變,變則通,我們就照著以下的這篇文章,在自個的Mac電腦,使用OpenSSL,自個開家CA;自己發伺服器憑證申請(CSR);自己透過自家CA核發伺服器憑證.......

How to create a secure (HTTPS) OS X Web Server 

然後,自己吃自己......

啊!寫得太順,寫多了!     ^^"

在 AWS EC2 雲端主機安裝 MongoDB

學著用MongoDB已好一陣子了,一直沒搞清楚,這到底是「芒果DB」;還是「蒙古DB」?

如果是「蒙古DB」,會讓人聯想到「蒙古大夫」,那......將資料存放在這,會不會有些令人擔憂?!    ^^"

在我的Mac電腦,研習MongoDB一陣子後,具備一些基本的掌握度了。所以,接著也想將MongoDB,安裝在我EC2的雲端主機上,啟動運轉,開始使用。

「如何在 AWS EC2 雲端主機安裝 MongoDB? 」,在網路搜尋先知先覺的PO文,結果,找到如下的這篇,依著指引照著做,一次就搞定。

Installing MongoDB on an EC2 Linux instance

提供給需要的同好做參考,但請注意,這篇的作法僅用於AMI版的Linux;不適用於Ubuntu版。

完成安裝後,應該心情很High;感覺Very good吧?!

但.......,能確定安裝與設定都正確了嗎?那MongoDB Service果真已能正常運作了嗎?

為求確認,以便心安,所以,需要有「作法」能夠驗證。我個人的驗證作法,會針對如下兩項目標進行檢驗:
  1. Service在作業系統中,是否已在執行?
  2. DB的指令,是否能夠操作資料庫?

至於以上兩項的驗證目標,其執行的細節程序如下:

【註】:文字背景標黃色處,表「個人需輸入的指令」;文字前景標紅色之字,表「需要目視檢查驗證的輸出結果」。

驗證Services已在執行

$ service mongod status
/etc/init.d/mongod: line 69: ulimit: open files: cannot modify limit: Operation not permitted
mongod (pid 8645) is running...

驗證可使用DB指令,進行資料操作

$ mongo
MongoDB shell version: 2.4.7
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
     http://docs.mongodb.org/
Questions? Try the support group
     http://groups.google.com/group/mongodb-user
> db.test.save({a:1})
> db.test.find()
{ "_id" : ObjectId("5270748a601825edfa039398"), "a" : 1 }
> exit
bye


2013-10-18

Dev HTTP Client 測試 REST API 的好工具

有在開發符合 REST 規格的 API 嗎?怎麼測試?

有人向你反應,他的程式呼叫你開發的 API (REST) ,所得到的結果有錯/異常收不到結果......,該怎麼診斷,以判斷是否真為你 API 的 Bug ,還是其它的問題導致?

這裡有個好用的 REST Client 工具,只要在 Google Chrome 瀏覽器安裝這個「擴充功能(extensions)」,就能使用。

https://chrome.google.com/webstore/detail/dev-http-client/aejoelaoggembcahagimdiliamlcdmfm

最近在學 Web Client 端的 JavaScript 技術﹣Backbone JS;在 Web Server 端,我用的是 Node.js 。

由於新手上路,當 Backbone 的 Model、Collection 物件,無法自 Server 端正常取得資料,這時我需要釐清,是 Server 端的 Node.js 程式碼有錯?還是 Client 端的 Backbone 程式沒搞對?

有了這個工具的協助,問題的導因很快就快界定,Oh Yeh! ^^y



高勝美歌曲集

很久,很久以前,有個「金八點」很紅。
後來,長江後浪,推來一個「高八點」,也很紅。

有多紅?

計程車的司機杯杯,曾經這麼說:「我們十台計程車,就有九台是播放高勝美的卡帶;那台沒播的計程車,是因為卡帶機壞掉了!」 ^^"


2013-10-17

讀藺相如傳

翻開戰國史,多少六國的王候,聽到要與秦國會盟,就嚇個半死,而藺相如的不怕死,在「澠池之會」震懾秦王;嚇退秦國侍衛,可知藺相如絕非膽小怕死之徙。再論其謀略與辯才,在「完璧歸趙」、「澠池之會」的故事中,可知其才智及雄辯之能,絕非泛泛之輩。

可是,如此一個不簡單的利害角色,卻只為了一個簡單的理由﹣「相忍為國,以國為重」,面對官位比他低階的廉頗將軍,則寧可裝小孬孬......

像藺相如這種有勇、有智、有謀、有所不為,真正的「大丈夫」,不知咱們台灣是否也找得到?!

還是只能空歎:
「哲人日已遠,典型在夙昔」...... T__T



《完璧歸趙》



在公元前283年,趙惠文王取得了楚國和氏璧秦昭襄王在聽到這個消息後,派人遣書趙王,表示願意以十五座城池交換和氏璧。趙王與大將軍廉頗等諸位大臣商議,但最後得不出結論,因為奉璧予秦國,則害怕得不到城池,不奉璧予秦國,則害怕被其攻打。

就在這個懸疑未定之時,宦官頭目繆賢上前向趙王獻計,表示其門客藺相如可以出使秦國。趙王則問:「何以得知?」 繆賢則表示以往他曾經犯罪,欲逃亡燕國,但藺相如阻止他,並問向他曉以利害,最後他亦因為沒有出走燕國,反而得到趙王饒恕的機會。因此他認為藺相如有智有謀,可委以重任。

趙王於是召見藺相如,並詢問藺相如應否以和氏璧換取十五座城池。藺相如向趙王分析,秦強趙弱,不可不換。但趙王問如果給予秦王和氏璧,而秦王不給予他城池,可以怎辦。而藺相如則回答說不論怎樣,趙國都要冒風險,寧可秦國理虧,也不可讓趙國理虧。並且表示他願意攜璧入秦,而且如果秦王反悔,必保證完璧歸趙,趙王於是派他出使秦國。

秦王於章臺接見藺相如,藺相如奉璧予秦王。秦王喜形於色,將和氏璧傳給美人及左右觀看,這時左右皆呼萬歲。藺相如看出秦王無意將城池給予趙國,於是向秦王說和氏璧有瑕疵,想向秦王指出,並向秦王取回璧玉。藺相如在取回和氏璧後即站在大柱旁,向秦王說:

「趙王在眾臣異議中仍力排眾議,接納臣之提議,因為布衣之交尚不相欺,何況秦國為一大國!趙王為了保存秦趙之友好,在齋戒五日後使臣奉璧入秦。可惜秦王不但沒有給予趙國城池的打算,而且還將和氏璧傳給美人,實在是對臣的戲弄。」

說畢後,藺相如即作出撞柱的姿態,而秦王因為怕破壞了和氏璧,於是假意給予趙國十五個城池,但實際為全不可得到的地方。藺相如看穿了秦王的奸計,於是借故要秦王齋戒五日才奉上和氏璧,以拖延時間。就在這數天,藺相如派侍從攜璧返回趙國,自己留下應付秦王。

秦王在齋戒五日後,於大殿上設置九賓之禮,並傳召藺相如,藺相如應召上殿,並向秦王說:「秦國自秦繆公以來二十餘位君主,並未有信守誠諾者。因此臣誠恐秦王欺騙趙國,已命人持璧歸趙。秦強而趙弱,如果大王先割十五城予趙國,再派遣一位使者至趙國,趙國立即交出和氏璧。臣知道欺騙大王之論罪當誅,所以臣請赴湯鑊之刑,並不會有任何異議。」秦王與其群臣只得苦笑,這時左右之人正想將藺相如帶去行刑。但秦王卻制止,認為即使殺了藺相如亦不會有大作用,不如放了他,保存秦趙之間的友誼。結果藺相如成功完璧歸趙。

藺相如歸國後,趙王認為不辱使命,保存了趙國的體面,於是封其為上大夫。結果,秦國不給予趙國城池,趙國亦不給予秦國和氏璧。


《澠池之會》


秦王因完璧歸趙一事惱羞成怒,派大將白起發兵攻,奪取簡(今山西離石縣西)和祁(今山西祁縣),次年再奪取石城(今河南朴縣西南)。又次年,再攻趙,殺死趙國軍民二萬人。

前279年,秦昭襄王取勝後,為了集中力量攻打楚國鄢郢之戰),派出使者告知趙惠文王,表示欲與趙王停戰,重修舊好,並相約於西河外澠池(今河南澠池縣)會面。趙王畏懼秦國,不願赴會。廉頗藺相如則獻計說:「王上如果不赴會,則是示弱而秦。」於是趙王決定赴會,並命藺相如率精兵五千相隨,又派了平原君趙勝率領數萬趙軍在澠池附近。廉頗送他們至邊境,並向趙王說:「王上此行,直至整個會議完畢,最多不過三十日便可歸國。如果三十日後仍不歸國,則請立太子為王,以斷絕秦國藉此要脅的希望。」趙王在思考一番後,決定答應,免得趙國被秦國要脅。

趙王到達後,會議便開始,依據古代習俗,兩國國君相會,定必大飲一番,所以秦王和趙王皆飲了數杯。秦王說道:「寡人聽聞趙王愛好音律,不如請趙王上前演奏瑟樂。」趙王不好意思推擋,只好勉強鼓瑟。秦國御史記下此事:「某年月日,秦王與趙王相會飲酒,秦王命令趙王鼓瑟。」藺相如上前說道:「趙王亦聽聞秦王善於演奏秦國樂器,臣請秦王演奏盆樂,以互相娛樂。」秦王大怒,決不答應。於是藺相如向前進,並跪請秦王。秦王堅決不肯擊盆,藺相如說道:「五步之內,相如可以刎頸以血濺大王!」

這時左右的侍衛欲以刀斬殺藺相如,藺相如怒目視之,大聲叱喝,侍衛無不畏懼,只得退開。秦王無奈,惟有擊盆一次。藺相如即召趙國御史記下此事,說道:「某年月日,秦王為趙王擊盆。」秦國的群臣即說道:「請趙國以十五座城池為秦王祝壽。」藺相如即時回敬:「請秦國以首都咸陽為趙王祝壽。」最後直至會議終結,秦王都不能羞辱趙王,趙國亦於邊境部署重兵以對付秦國,結果秦國不敢輕舉妄動。

趙惠文王二十年的澠池會盟是秦昭王為了方便集中力量攻打楚國,於是想同趙國講和。澠池之會後,相如以功授官為上卿,位在廉頗之上,廉頗不服氣,以致於有後來的負荊請罪。澠池之會後,秦、趙間暫時停止了戰爭。趙軍立即出兵齊國,攻下高唐等地。


《負荊請罪》




藺相如因澠池之會被拜為上卿,廉頗深深不忿,說道:「我身為趙國將軍,有著攻取城池,野外戰鬥獲勝之大功,而藺相如則只是以伶牙利齒出眾,從而位居於我之上。而且藺相如出身卑賤,要我位居其下,對我而言實在是極大羞辱。」於是廉頗便對外宣稱,如果他看到藺相如,必定對其大加羞辱。

藺相如在得知此事後,不肯與廉頗會面。在早朝時,經常稱病不去。有一次,藺相如出門時,在遠處望見廉頗,即時改變行車方向,以躲避他。但這個舉動使得其門客亦感到羞恥,質疑藺相如膽小怕事。藺相如無奈,只有向其說道:「大家認為廉將軍可否與秦王相比?」眾人回答:「不可」。藺相如再說道:「即使以秦王之淫威,我也敢在大殿上對其叱喝,並羞辱秦國群臣。我雖然不是甚麼勇者,但怎麼可能怕廉將軍?其實我只是顧念趙國之社稷,因為強秦之所以不敢攻打趙國,是因為有我們兩個人在。兩虎相鬥,必有一傷。如果我公然跟廉將軍鬧翻,秦國必定趁機出兵攻趙,趙國就危險了。我之所以如此躲避廉將軍,實在是因為國家大事遠較個人恩怨為重。」廉頗在得知此事後,即時袒露背部,並背負荊棘至藺相如門前謝罪。

廉頗見到了藺相如說:「我是個粗魯人,見識少,氣量窄。哪兒知道您竟這麼容讓我,我實在沒臉來見您。請您責打我吧。」藺相如連忙扶起廉頗,說:「咱們兩個人都是趙國的大臣。將軍能體諒我,我已經萬分感激了,怎麼還來給我賠禮呢?」

兩個人都激動得流了眼淚。打這以後,兩人就做了知心朋友。

2013-10-16

Carpenters合唱團 (播放清單)

聽 Carpenters 的歌,好像是一個多年的好友,在你身旁,細訴過去種種.......

清晨時分,聽著古老的甜歌! U__U


2013-10-02

Oh Yeah.....! WebStorm 7 支援 Terminal 囉!

WebStorm 7 已經推出了!

這個新版本有那些功能,目前沒花時間一一細看。   ^^!!
當我安裝完 WebStorm 7 後,透過其 UI 操作介面,亂玩一通,結果......

發覺現在的 WebStorm 7 也支援 Terminal 功能了,耶~~~!  ^^y

因為,最近一直在研習及使用 Node.js ,為了要安裝 Module ,我都是先修改 package.json 檔,在 dependencies 中新增需要添加的 Module Name ,然後再切換到 Mac 的 Terminal 視窗,執行「npm install」(其中,還有需要使用 cd 指令,切換目錄的繁雜細節工作)。

現在,有了這個新功能,在 WebStorm 的 IDE 環境中,修改完 package.json 檔後,便可以直接在內嵌的「Terminal」窗格中,輸入 npm install ,完成 Module 的安裝工作。

Hmmm........  足爽!   ^^y




WebStorm 7 參考資訊: