標籤:

Node.js 都應用在什麼項目上?這些項目為什麼選擇 Node.js?


都用在了哪些項目上不清楚,不過可以說說node適合用在什麼場景下。

首先,node新開一個http連接的開銷,相當於一個大函數調用,相比php的新開線程動輒花費2MB內存和上下文切換的漫長時間,已經很小很小了。所以,node天生就是為高並發的應用而誕生,在設計之初就承載著巨大的使命。而這種極度追求代碼效率和美感的設計,是以提升學習理解的難度,和考驗編程能力為代價。如果你像我一樣,有代碼潔癖,追求極致,那麼node將是不二選擇。如果你僅僅是為了完成工作,或者快速搭建項目上線運營,那麼還是用php或其它什麼看似方便卻一點也不「美」的語言吧。

再者,由於js的非同步特徵,始終有用戶代碼在執行,省去了等待查詢資料庫和文件系統的時間,相比CPU的時鐘頻率,去讀一次資料庫太久太久,久到讓CPU等得花兒都謝了。node讓CPU不在等待,node讓媽媽不用擔心我的內存。但是這種高效運用CPU的非同步回調,將會帶來邏輯上的混亂,一不小心就會一團亂麻理都理不清,下文有敘。

以上兩點,導致node適合在具有大量細小的http請求環境下工作,典型的就是一個web即時聊天程序,或者一個支撐上萬人同時在線的遊戲伺服器。你甚至不用考慮http請求數太多的問題。

如果用node開發網站,你可以把數據請求分的很細,也就是說不必像php那樣把所有數據一次性載入到客戶端,而是載入一部分,讓瀏覽器渲染頁面的同時,再去載入另一部分。Facebook的頁面優化技術(叫big...什麼的,我忘了),就是這種分塊載入的模式。可以讓頁面的載入速度在用戶體驗上提升5到10倍。

node無論從代碼執行速度,還是開銷,都是最完美的選擇。但是缺點在於js非同步特徵的難以理解和控制,如果沒有相當過硬的js開發經驗和特徵理解,項目稍微大一點,代碼結構就會一片混亂。node是在考驗一個人的代碼設計和掌控能力,如同九陰真經,練的好就一身絕學獨霸武林,練的不好就走火入魔精神崩潰。動不動就長達8層的回調嵌套,可不是鬧著玩的。除了採用step同步方案解決控制流倒置和深層回調嵌套問題,把數據請求分得很細,再分多次載入,不僅在代碼流程上更美觀,也更符合node的特性。

有人說,非同步代碼是反人類的。其實同步執行才是反人類。想像一下,你需要列印一疊材料:印表機開始工作後,你站在那裡等著,5分鐘後列印完畢,你取走材料回到辦公室。這似乎沒什麼。但是如果有100份需要列印?10000份呢?你也站在那裡乾等著?還是趁這個時間喝杯咖啡,或者多寫幾個 if else 吧。

- - - - - - - - - - - - 2014/3/10 更新 - - - - - - - - - - - -

列幾個我知道的國內項目吧

1.雪球 - 雪球

2.花瓣 - 花瓣網_發現、採集你喜歡的一切(家居,美食,時尚,穿搭,設計,商品,美圖等)

3.淘寶指數 - 淘寶指數 - 淘寶消費者數據研究平台

4.CSDN Share - Share頻道 - CSDN.NET

5.酷廚 - 酷廚網 - 天下美食 盡在酷廚 | coochu.com

6.Worktile - Worktile 讓工作更簡單

7.兔耳日記 - 兔耳日記 | 首頁

8.牧客 - http://www.imokee.com/

9.君鑒 - 君鑒

另外附上一個Node.js框架:

Codekart - CodeTank 歡迎使用Node.js前後端一體化開發框架 !

Github地址:myworld4059/Codekart · GitHub


https://github.com/joyent/node/wiki/Projects,-Applications,-and-Companies-Using-Node


運營了一段時間的 http://OurJS.com, 目前已經完全開源( newghost/ourjs ),談一談經驗:

很長時間以來,OurJS一直運行在最低配置的雲伺服器上,(其實此伺服器上還有一些其他網站,流量都不大較,還有一些輔助軟體,如SVN、FTP、Nginx,微信號Server, 郵件伺服器,均由node驅動),目前並沒有滿負載運行,一般1~2個月有重大升級時才會重啟一次。

一句話總結就是可以以較少的伺服器資源支承起較大流量。(至少目前還沒有遇到瓶頸)

內存佔用:

OurJS項目主頁(http://code.ourjs.com),國外,AWS, Debian系統, 內容較少, 0.612G內存

root 1165 1.4 5.2 630868 32692 ? Sl 12:46 0:12 /root/local/bin/node /var/www/ourjs/svr/ourjs.js config.magazine.js

內存佔用 0.612G X 5.2% = 32.6Mb (剛安裝時的情況,因流量不大,一直沒什麼變化)

OurJS主站(http://ourjs.com),國內,Debian系統,跑了一年,內容較多,因一個微信服務號要佔用20%內存,前不久將內存從512Mb升到了1G。

root 7816 48.7 7.6 664912 78420 ? Sl Aug13 701:59 /root/local/bin/node /var/www/ourjs/svr/ourjs.js config.newspaper.js

內存佔用 1G X 7.6% = 77.8 Mb (映像里沒有超過10%的情況)

流量情況:

OurJS的流量中等,峰值 &> 1W (截至2014-8), 曾經在GA在線觀測到200多人在線,並ps aux查看到的內存消耗與閑時差不多。

因為node.js的非同步模型,內存消耗基本跟訪問量無關,沒有線程去消耗內存資源,所以一般幾百塊錢的伺服器即可滿足較大流量的需求。

node.js的缺陷

剛開始採用node.js的時侯,確實會碰到一些問題,但隨著時間的推移,個人感覺這些問題都不大,都是可以克服的。

1) 回調地獄

回調是不可避免的,比如:

http.createServer(function (req, res) {
console.log(new Date());

//callback hell!!
cookie(req, res, function(req, res) {
session(req, res, function(req, res) {
permission(req, res, function(req, res) {
paramParser(req, res, function(req, res) {
bodyParser(req, res, function(req, res) {
dbSelect(req, res, function(req, res) {
dbUpdate(req, res, function(req, res) {
res.end("done!");
})
})
})
})
})
})
})
}).listen(8080, "127.0.0.1");

看起來確實有點噁心,但這一點可以在架構級別解決(個人並不是非常喜歡promise的解決方案)比如使用鏈式結構,而非嵌套結構, 如:WebSvr中的filter寫法(OurJS 的基礎框架),偽代碼,跟express中的use類似

var webSvr = new require("websvr")();

webSvr.start();

webSvr.filter(function(req, res) {
cookie(req, res, function() {
req.filter.next();
});
});

webSvr.filter(function(req, res) {
session(req, res, function(req, res) {
req.filter.next();
});
});

webSvr.filter(function(req, res) {
paramParser(req, res, function(req, res) {
req.filter.next();
});
});

//and so on ...

webSvr.url("/", function(req, res) {
res.end();
});

或者使用JavaScript天生的事件通知來解決,至少結構看上去更合理。

Schema.notify.on("done", function() {
initData();
initPlugins();
});

//或
Articles.notify.on("done", function() {
articlesCount.refresh(Articles);
});

2) 異常處理及Debug困難

第二個普通觀點認為:「Node.JS進程不可靠,一遇到unexecept error整個線程就掛掉「,目前幾乎已經碰不到這種情況了,因為每一個callback的異常都是可以捕捉到的,一個websvr只要能正常開啟,異常就必定只能在回調中產生,只要架構設計合理,只需加一處try catch就可以打出調用堆棧,定點排錯。

如,這裡有一個錯誤:

var webSvr = new require("websvr")();

webSvr.start();

webSvr.url("/error", function(req, res) {
var b = req.params.json.b; //b是不存在的
res.end(b);
});

在地址欄中輸入: http://localhost:8054/error 則會直接在console和網頁中輸出錯誤:

Error 2014-08-14T09:48:44.880Z /error
TypeError: Cannot read property "b" of undefined
at c:githubgoscript
ode-error-2-websvr.js:6:26
at parseSession (c:githubgoscript
ode_moduleswebsvrwebsvrwebsvr.js:208:9)
at parseBody (c:githubgoscript
ode_moduleswebsvrwebsvrwebsvr.js:251:9)
//...

找到第6行即可, 並且此錯誤並不會影響其它request

在http://ourjs.com還使用了一個shell來確保web服務永遠執行,並記錄錯誤日誌,(在nodeV10.21前,似乎確實有一個底層的讀取文件流文件流BUG,Exception從libuv層拋出,導至node進程崩潰,這些底層error在js中是捕捉不到的。不過隨著node的完善,這種BUG應該會越來越少)

while true; do
{
node ./svr/ourjs.js config.newspaper.js

echo "Server stop working, waiting for restart...

"
sleep 5
} 2&>&> ./error.log #關鍵, 將錯誤(2) 輸出到log文件
done

所以關於node.js 異常處理不強和無法Debug也是可以解決的。

先寫這麼多……


智能dns webserver 操縱spark/hadoop nosql的mapreduce演算法 桌面 移動 嵌入

無所不能


node適用於實時的web服務處理。比如股票實時信息,websocket應用。restful api架構。千萬別拿node做複雜邏輯的東西!千萬!


手機端的restful服務一般會用,這些服務的邏輯比較簡單,對服務的速度和性能要求高。


人生苦短,別跟機器較勁,能扔給硬體的都扔給硬體吧,懶惰是程序員進步的動力。所以,反人類的非同步的nodejs,還是適合用在邏輯簡單的場景下,起碼是每次請求的邏輯簡單。


NodeJS 用於編寫前端開發中需要用到小工具挺爽又快, 比如構建工具 mod, grunt, 合圖工具 ispriter等等


nodejs的非同步回調明顯反人類,這不就多說了。俺覺得它最大的好處還是歸結到前後端可以同一語言,試過meteor的人都說好。(當然有個很重要的原因是meteor用fiber/future把代碼寫成同步調用方式,所以順眼和容易維護多了)

前後端同一語言的好處:

1. model可以共用,當然前端可能只取部分field,但model的知識定義還是只有一份的

2. 參數驗證的代碼可以共用

3. 程序員好招,一個人可以通吃了


推薦閱讀:

如何利用mongodb+node.js完成一個搜索的功能?
有哪些比較好用的nodejs模塊?
有哪些值得推薦的針對 Node.js 本身而非 Express 框架之類的學習資料?
NodeJS的desktop應用開發中,關於Electron的中文文檔或者博客之類的很少?
為什麼nodejs的module.js里用了readFileSync而不用readFile?

TAG:Nodejs |