1.2. 統一環境
開發環境
- nvm
- nrm
- nodejs 0.10.38
- node-inspector
部署環境
- nvm
- nrm
- iojs 2.x
- pm2
- nginx
異步流程控制:Promise是唯一選擇,而且從一開始就要強制使用,絕不可忽略,這關系到設計思維的巨大差異,甚至關系到我們是否真正能夠在 node.js方向堅持下來。我們用Q.js,和前端Angular.js使用的微縮版Q.js保持一致,減少學習周期。
1.4. 啟動開發模式
因為我們在開發過程中總是希望修改后立即看到效果,而不是每次都要終止進程並重啟。
supervisor 可以幫助你實現這個功能,它會監視你對代碼的改動,並自動重啟 Node.js
開發模式我推薦 supervisor
安裝
npm install --save supervisor
啟動
supervisor app.js or supervisor www/bin
我的實踐是把package.json里的start
"scripts": { "d": "node-debug app.js", "start": "./node_modules/.bin/supervisor app.js" }
然后
npm start
還有一個庫也不錯,叫nodemon
see http://nodemon.io/
1.5. 調試模式
推薦node-inspector
安裝
npm install --save node-inspector
啟動
node-inspector app.js or node-debug www/bin
我的實踐是把package.json里的d里
"scripts": { "d": "node-debug app.js", "start": "./node_modules/.bin/supervisor app.js" }
然后執行
npm run d
npm run命令詳解,見https://github.com/i5ting/npm-run-test
1.6. 啟動產品上線模式
產品模式我們推薦使用pm2
pm2是非常優秀工具,它提供對基於node.js的項目運行托管服務。它基於命令行界面,提供很多特性:
- 內置的負載均衡器(使用nodecluster module)
- 以守護進程運行
- 0s(不間斷)重啟
- 為ubuntu/ CentOS 提供啟動腳本
- 關閉不穩定的進程(避免無限死循環)
- 基於控制台監控
- HTTP API
- 遠程控制以及實時監控接口
pm2使用nodecluster構建一個內置的負載均衡器。部署多個app的實例來達到分流的目的以減輕單app處理的壓力。
安裝pm2
sudo npm install -g pm2
查看基本幫助文檔
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 updatePM2 More examples in https://github.com/Unitech/pm2#usagefeatures Deployment help: $ pm2 deploy help
上面基本是我們比較常用的
1.7. pm2的最佳實踐
把啟動寫到json配置文件中
// 20150531071243
// https://raw.githubusercontent.com/RocketChat/Rocket.Chat/master/pm2.production.json { "apps": [ { "name": "rocket.chat.0", "max_memory_restart": "1024M", "log_date_format": "YYYY-MM-DD HH:mm:ss SSS", "script": "/var/www/rocket.chat/bundle/main.js", "out_file": "/var/log/rocket.chat/app.log", "error_file": "/var/log/rocket.chat/err.log", "port": "8080", "env": { "CDN_PREFIX": "//dbde4sd21oahf.cloudfront.net", "MONGO_URL": "mongodb://localhost:27017/rocketchat", "MONGO_OPLOG_URL": "mongodb://localhost:27017/local", "ROOT_URL": "http://rocket.chat", "PORT": "8080" } }, { "name": "rocket.chat.1", "max_memory_restart": "1024M", "log_date_format": "YYYY-MM-DD HH:mm:ss SSS", "script": "/var/www/rocket.chat/bundle/main.js", "out_file": "/var/log/rocket.chat/app.log", "error_file": "/var/log/rocket.chat/err.log", "port": "8081", "env": { "CDN_PREFIX": "//dbde4sd21oahf.cloudfront.net", "MONGO_URL": "mongodb://localhost:27017/rocketchat", "MONGO_OPLOG_URL": "mongodb://localhost:27017/local", "ROOT_URL": "http://rocket.chat", "PORT": "8081" } }, { "name": "rocket.chat.2", "max_memory_restart": "1024M", "log_date_format": "YYYY-MM-DD HH:mm:ss SSS", "script": "/var/www/rocket.chat/bundle/main.js", "out_file": "/var/log/rocket.chat/app.log", "error_file": "/var/log/rocket.chat/err.log", "port": "8082", "env": { "CDN_PREFIX": "//dbde4sd21oahf.cloudfront.net", "MONGO_URL": "mongodb://localhost:27017/rocketchat", "MONGO_OPLOG_URL": "mongodb://localhost:27017/local", "ROOT_URL": "http://rocket.chat", "PORT": "8082" } }, { "name": "rocket.chat.3", "max_memory_restart": "1024M", "log_date_format": "YYYY-MM-DD HH:mm:ss SSS", "script": "/var/www/rocket.chat/bundle/main.js", "out_file": "/var/log/rocket.chat/app.log", "error_file": "/var/log/rocket.chat/err.log", "port": "8083", "env": { "CDN_PREFIX": "//dbde4sd21oahf.cloudfront.net", "MONGO_URL": "mongodb://localhost:27017/rocketchat", "MONGO_OPLOG_URL": "mongodb://localhost:27017/local", "ROOT_URL": "http://rocket.chat", "PORT": "8083" } } ] }
部署
pm2 deploy ecosystem.json production setup
第一個傻瓜原則,你的機器有幾核,你就幾個實例
Start an app using all CPUs available + set a name : $ pm2 start app.js -i 0 --name "api"
上面的配置文件了配置了4個,你應該能自己估算出點什么
第二個傻瓜原則,想機器癱瘓么?最簡單的辦法是內存不足,怎么樣能防止內存被吃盡呢?
很簡單,和lru cache一樣,設置最大可用內存,防止內存用爆
參數里
--max-memory-restart <memory> specify max memory amount used to autorestart (in megaoctets)
配置文件了也一樣
"max_memory_restart": "1024M",
4個實例,每個可占用內存為1G,那么你應該能自己估算出點什么
第三個傻瓜原則,敏感信息咋辦?有2種辦法
- 使用config/default.example.json。部署的時候拷貝一份,然后按需修改
- 使用pm2的env,在環境變量里配置,pm2的json是在服務器上生成的,每個服務器都要生成一次的
推薦pm2的env這種方式,相對更簡單點
第四個傻瓜原則,集群狀態下的應用應該是stateless的(無狀態),不能依賴代碼去做一些事兒的,比如自己寫隊列處理cache
因為每個實例都是獨立的,你讀寫不是全局的,一定會有各種問題,盡量使用第三方獨立的服務,比如配置文件(非實例下面),比如redis等緩存,db等
1.8. pm2高級用法
1.8.1. reload
啟動的時候會指定一個名字,以后根據該名字,進行特定操作
pm2 reload some-app
它的好處是0秒延時,可以和nginx -s reload
媲美
1.8.2. monit
pm2 monit
更多內容 https://github.com/Unitech/PM2#monitoring
1.8.3. 日志
更多內容 https://github.com/Unitech/PM2#log-facilities
$ pm2 logs
$ pm2 logs big-api $ pm2 flush # Clear all the logs
1.8.4. web
npm run web
訪問 http://127.0.0.1:9615
1.8.5. 開機啟動
pm2 startup centos
注意:示例的package.json里給出的是centos里增加開機啟動項,如果是其他操作系統,請自己更改
更多內容 https://github.com/Unitech/PM2#startup-script-generation
$ pm2 startup <ubuntu|centos|gentoo|systemd>
開機啟動,還要注意的一點是要保存一次pm2運行數據的
pm2 save
1.9. 要不要nginx 或者 haproxy ?
nginx
- 主要做反向代理和靜態資源處理(如果沒有cdn,就把public下的內容放到nginx里)
- 負載
- 阻止了很多常見的攻擊和慢客戶端
nginx負載對應多台機器,每台機器里起多個(cpu個數)實例,單機負載使用pm2管理。
nginx和haproxy都是針對多台機器的負載,功能差不過,使用和插件方面,nginx稍強一點,知名度更高一點
1.10. 另外一種部署方式
passenger是rails部署時常用的服務器,不過慶幸的是這幫貨出了node版本,而且性能不錯
有興趣的可以去研究一下 nginx + passenger
1.11. mongodb的部署
- 安全 https://cnodejs.org/topic/54cdd026ef1b48510c27e07a
- 集群 http://www.linuxidc.com/Linux/2015-02/113296.htm
1.12. redis部署
http://www.linuxidc.com/Linux/2014-07/104306.htm
1.13. 簡單壓測
- apache ab
- wrk
1.14. node cluster和nginx負載性能比較
todo
別人測試的node的性能稍高,不過我還是想自己測測
1.15. 性能調優
todo
1.16. keeplive
- http://www.bubuko.com/infodetail-260176.html
1.17. 監控
- newrelic https://cnodejs.org/topic/53fde58d7c1e2284785cd39e
1.18. 資源
- http://promotion.pm2.io/
- https://github.com/Unitech/PM2
- https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps
如果你正在找Node.js的學習資料及指南,那么請繼續(閱讀),我們的教程將會覆蓋即時聊天應用、API服務編寫、投票問卷應用、人物投票APP、社交授權、 Node.js on Raspberry Pi等等。
以下是Node.js入門的簡單介紹,如果你對Node.js略有了解可以直接跳過此部分。
那什么是Node.js呢?
Node.js是迄今運用最多的服務端JavaScript運行時環境,使用JavaScript開發跨平台的實時WEB應用。
Node.js基於Google的V8 JavaScript引擎。基於事件驅動,非阻塞的輸入輸出模型,這也使得其高效而輕量。
Node.js的強大之處在於其能力支持數據密級性的交互應用,因為這類應用的函數圍繞着用戶事件,數據I/O和數據流的處理。對於JSON的API,Node.js同樣顯得很神奇,它是單頁WEB應用的心臟和靈魂。
Node.js的流行程度可以感覺得到,像eBay、target、City Group、Sony、Uber、LinkedIn、Medium、Netflix等等的大公司都有在他們的web項目中應用。
怎樣學習Node.js呢?
Node.js的開發者來自全球,他們用Node.js開發復雜交互的,數據密集型的WEB Apps和網站。同時網上有着大量的資源和教程教你怎樣構建自己的Node.js應用。
我們不防看看Node.js大神針對Web Apps寫的Node.js最佳指南。
我們所覆蓋的指南將包括針對初學者的Node.js、中級指南,同時還有教你怎樣構建復雜的Node.js項目。
對於完全的Node.js初學者, 在深入挖掘本文章后續提到的學習項目之前,一步步按照airpair.com上面入門指南的要點 或 Node.js入門指南 之類的文章學習是不錯的選擇。Nodeschool.io是另一個比較好的網站,上面有着非常多的資料,可以學習基本的node.js及相關的技術。
通過Express框架和Socket.io構建即時通訊APP
將一個新技術學到一定高度的最好方式就是通過功能性的應用了。在這個指南中,你將學習使用Express框架和Socket.io構建即時通訊應用,這些技術可以使用基於事件的雙向通信。在這個指南中,你還將使用JavaScript模板引擎Jade。
我們要介紹的指南由Krasimir Tsonev所撰寫,發布在tutsplus.com上面,從node.js的環境搭建,使用Express框架的后端服務,到最后使用Jade模板引擎的前端UI開發,覆蓋了所有前端到后端的方方面面。
你可以在后面這個鏈接中找到這篇指南: 即時通訊(Node.js Tutorial – Real Time Chat) .
使用Swagger創建Restful API
這個精心設計的教程解釋了如何使用Swagger來創建Rest API,並且包括了Rest API應該支持的所有操作(CRUD,創建,查詢,更新,刪除)。這個例子是由來自scotch.io的Samuela Zara提供的,它實現了管理電影集合的Rest API。
Swagger是一個非常強大的框架來描述REST APIs,它提供了交互式的API文檔編輯,客戶端sdk生成以及發現服務。通過使用Swagger,你所書寫的API將更容易被大家所理解並且使用。
在這個教程中,Samuela一開始先教會大家如何安裝node.js的Swagger模塊,然后介紹了Swagger提供的模擬模式。通過這個模式,API開發者可以先集中精神進行API本身的設計,而不用寫一行的代碼。當這個API結構被設計完成之后,教程開始帶領大家具體實現獲取電影,增加/修改電影以及刪除電影的操作。
你可以通過Restful API in Node.js using Swagger這個鏈接來訪問該教程。
在 Node.js 中使用 Nodal 建立 API Services
在大多數模塊和框架之上,你就不會需要再建立任何簡陋的 JavaScript/Node.js 項目。為了多平台(移動端,web,IOT)產品開發,面向服務的架構是關鍵的,而本教程就將帶你更進一步。
在本教程中,Keith Horwood 利用 Nodal 框架在 Node.js 中來創建 API services,並讓這一切看起來極其簡單。Nodal 是一個可擴展的,以意見為依據的全服務框架,它幫助數據中心加快在 Node.js 基礎上的API創建。
在本教程中,你將會在開發 MVC (模型,控制器和視圖)之前安裝 node.js 環境,安裝 Nodal 和 postgreSQL。
你可以在這里找到本教程: 在 Node.js 中使用 Nodal 建立 API Services.
Node.js Apps - 使用通行證進行社交認證
社交認證幾乎隨處可見,因為我們絕大多數人在Facebook 、Twitter和Google這樣的某個社交網絡上都有自己的賬號。社交網絡認證的工作過程是使用已有的社交網絡證書進行單點登錄,同時可以登錄到其它的程序。
在本教程中,你會構建一個簡單的Node.js程序,通過使用通行證作為中間件使用社交認證進行登錄。本教程由Agraj Mangal編寫,發表在tutsplus.com網站上。
要獲得本教程可訪問鏈接Node.js Apps - Social Authentication with Passport.
使用Rethink DB和Node.js開發投票App
本教程主要針對的是對Node.js有基本理解的初學者。在本教程中,你能通過開發一個簡單的投票app學習Node.js,該程序給用戶提供投票的三個選項,並提供投票人數的實時更新。
Angular和angural素材設計庫用於程序的前端設計,Node.js用於服務器端,rethink DB用來存儲投票數據和相關聯的用戶數據。
通過編寫完成這樣一個簡單的程序,你就可以掌握創建整個程序的方方面面。
要獲得本教程可訪問- Polling App using Rethink DB and Node.js.
角色投票系統 – Node.js, React, MongoDB and Socket.io
這個教程是為有一定基礎的nodejs開發人員量身定做的,如果你是一個nodejs的初學者,那么這個教程並不適合閱讀。這是一篇由Sahat Yalkabov編寫的經過精心組織的教程,目的是為多人在線游戲(Eve Online)開發一個角色投票應用,這是一個功能完整的項目。Eve Online是一個多人在線游戲,每個玩家都有一個3D形象來代表他們的角色。
這篇教程覆蓋了一下這些內容:使用Node.js Express 框架創建REST API, 使用MongoDB進行數據的存儲,使用Socket.IO實時跟蹤在線的訪問者,使用React(和Flux)進行服務器端的頁面繪制,並且最終將這個引用部署到雲端。通過這個教程,你不僅能建成一個對Eve Online進行角色頭像投票的系統,而且還可以通過充滿樂趣的方式學習到許多的知識。
你可以通過下面的鏈接訪問這個教程 - Character Voting App – Node.js, React, MongoDB and Socket.io
使用 Node.js 和 Reactive.js 的 WI-FI 儀表板
這個教程是由 Marcello La Rocca 在 Sitepoint.com 上編寫的,適合中級的 Node.js 編程者。Marcello 的引領來自之前的系列教程,它還引導建立了一個儀表板添加更多關於周圍可連接 Wi-Fi 的信息。
在這個教程中,你實現的服務器運行在Ubuntu上,做一點小修改也可以運行在windows和mac上。服務器實現的擴展來自於 Marcello 之前的教程 - 使用 Node.js創建電池。實現服務器搭建之后,你編寫客戶端和用戶接口並使用HTML模板給當前的 Wi-Fi 列表。
你可以找到這個教程 使用 Node.js 和 Reactive.js 編寫 WI-FI 儀表板。
測試驅動的開發 - Node.js 和 Mocha
這篇由Semaphoreci.com提供的教程將交會你如何使用Mocha來進行單元測試和集成測試。
Mocha是一個JavaScript測試框架,它既可以運行在瀏覽器中,也可以運行在Nodejs環境中。Mocha將按照順序執行所有的測試,並將出現的未捕獲異常映射到相應的測試用例上。
你可以通過使用npm來引入mocha模塊。這個教程中的例子實現了一個顏色轉換程序,這個程序將RGB轉換成16進制形式。這個教程還創建了一個web服務器來測試異步代碼。
你可以通過下面的鏈接Test Driven Development – Node.js and Mocha找到這個教程。
在樹莓派上使用Node.js
這篇Node.js教程是"在創造中學習"(learning through making)系列的一部分,該系列由Dave Johnson編寫,發表在thisdavej.com網站上。通過本教程,你能學會在樹莓派2和樹莓派3上安裝Node.js。本教程自始至終主要關注的是在樹莓派上安裝Node.js。 學完本教程后,你可以進一步學習本系列中的其它教程,以便學會在樹莓派上使用Node.js,教程包括“探索使用Node.js在樹莓派上創建因特網web服務器”和“不用編碼而只使用node.js創建web服務器”。
要獲得本教程和其它相關的教程可訪問Node.js on Raspberry Pi。
Node.js教程:開發情緒分析應用
這是另一篇優秀的教程,由Scott Rich編寫,發表在IBM developerWorks上。本教程使用Node.js, Express框架, Sentiment模塊和ntwitter模塊開發了一個基於推特進行情緒分析的小型程序。 在本教程中,你將學習設置express框架,運行並測試hello Node.js程序,以確保框架工作正常,為程序添加情緒分析功能,並將程序連接到twitter,最后將它們整合在一起,以形成一個功能完整的程序。
在Twitter Sentiment Analysis App in Node.js上可以找到這篇教程。
貼士 1: 在開發環境使用 nodemon, 在生產環境使用pm2
當你第一次開發Node.js應用的時候, 其中一件事情就是一次又一次的運行[file].js 就和揭傷疤一樣。 當我第一次開發的node app時候,這個讓我感到異常挫敗和痛苦, 尤其是每當我修改很小東西的時候需要control+c
幸運的是我發現了一個非常棒的工具Nodemon
。 你可以利用以下的命令來安裝
1
|
npm install -g nodemon
|
Nodemon 是一個令人驚嘆的工具, 當你全局安裝它以后, 可以通過 nodemon [file].js 來啟動你的node.js scripts,它會告訴nodemon來監視你的script和scripts的所有變化, 這樣的Node.js開發方式非常震撼以及讓大大提高開發速度。
那么,生產環境又如何, 除非你用了heroku
,Nodejitsu
或者其它一些好的 Node.js 平台(也許它們有類似的功能), 但是碰巧你用了EC2 或者一些其它的雲平台來運行你的Node.js app, 你如何能然保證這是一個始終運行的Node.js app
案就是PM2, PM2 是一個類似於Nodemon的工具,不同之處在於它用於生產環境, 和Nodemon相似的地方在於它會監控你的app的任何修改或者重新部署,但是有更好的一面, PM2 在遭遇到崩潰的時候,它會正確重啟你的app。
PM2的優勝之處在於當你要將app需要多核處理的時候,PM2內部集成的負載均衡可以讓你很容易的去指定運行多少個實例。
1
|
pm2 start app.js -i max
|
-i
參數目的是指定運行多少個實例,在這個例子中 PM2 使用了一個常量max
來擴展你的app運轉到你最大的核數,不要忘記Node 平時只會運行在單核!
貼士 3: 輕松調試 Node.js apps
如果你從一個IDE重度集成的語言比如java 或者C# 轉來調試Node.js, 你一定會感到很困擾, 大部分新加入node的開發者采用了’flow’的調試模式,從這一刻開始你最好的朋友就是console.log
但是依然有更常見的調試方式來代替, Node.js 內置了一個調試器你可以稱為 node debug, 不過我更喜歡的 node-inspector
它們的github說 “Node Inspector 是一個使用Blink Developer Tools (以前稱為WebKit Web Inspector)node.js調試器的界面,”
簡而言之,node-inspector 可以讓你用任何你想用的編輯器和chrome web tools來調試你的應用,這是多么的性感。
Node-inspector 可以讓你做一些非常酷的事情,比如實時修改,單步調試,注入以及一堆其它非常酷的東西。
讓我們來根據指示一步一步安裝
https://github.com/node-inspector/node-inspector
貼士 4: Nodefly
一旦你有你的應用程序正常運行,你可能會問自己,你怎么可以監視它的性能和配置文件,以確保您的應用程序運行在最佳的速度。最簡單的答案是一個卓越的服務,我稱為Nodefly。
用簡單的一行代碼Nodefly開始監視你的應用程序內存泄漏,測量redis用了多久,mongo查詢和一堆其它很酷的東西。