標籤:

nodejs寫後端的時候如果需要添加功能是不是只能將nodejs服務停止才行?

比如說我在寫一個程序,用express框架監聽了80埠的/index 地址的get操作,並返回一個網頁。但是在這個之後突然需要添加一個對/data 地址的post操作,那麼我只能將node停止,添加完之後再開啟么?

如果這樣的話,豈不是很多的緩存都要重新進行緩存了,那麼對於這種情況有什麼好的解決方案么?


這麼多前端,想來寫NodeJS,然後他們首先覺得不爽的就是,瀏覽器調試可以不斷刷新,為毛服務端加一句代碼就要重啟一下服務?

卵而,服務端對可靠性要求非常高,在上線服務里,不可能會讓你隨便加新功能,還能隨時生效,隨時重啟什麼的。一般一個周發一個版就不錯了呢。

在本地開發,的確需要不斷重啟,用nodemon這個工具就能解決這個問題。

不要想著熱啟動,加了模塊自動載入新代碼什麼的,node進程重啟一下用不了幾秒鐘,如果你做過java開發,你就知道,這簡直太小兒科了

PS:對於樓主補充的信息的回答:

任何伺服器語言,都不要在進程里保存狀態信息。因為隨時都可能會重啟,不管是本地開發還是線上開發,重啟總是會發生的。不要把緩存放在進程里,放到redis里去。


首先回答問題本身:

nodejs寫後端的時候如果需要添加功能是不是只能將nodejs服務停止才行?

是,也不全是,通過hack require函數可以勉強做到一部分模塊的熱更新。一些模板文件通過對文件更新時間判斷可以決定要不要cache。

但是,熱部署的必要性並沒有那麼大。

流量小的網站即使停機部署也沒有太大問題,大不了就半夜上線唄。

流量大的網站即使能夠熱部署也不敢,最好還是切流量上線,現代的語言大多會有「預熱」的過程,比如JIT預熱。就算沒有,還有應用程序級別的各種緩存預熱這些類似的問題,比如PHP Smarty模板可以熱更新,但是一更新模板所有模板cache都會失效,瞬間CPU就打滿,會拒絕服務以及一些其他奇妙的事情*1。切流量上線可以慢慢把流量放起來這樣CPU曲線不至於太陡。

開發過程中用一個supervisor或者nodemon這類工具就搞定了不需要手工重啟,反正他重啟的速度一般而言都比人從編輯器切換到瀏覽器速度快。

*1:Smarty在編譯的時候CPU壓力很大,容易造成php-cgi超時,有小概率會造成模板cache文件寫到一半以後php-cgi被掐斷,這時候緩存文件的時間戳是新值,後續模板文件沒有更新的話就不會對它進行更新,而它可能只是一個編譯到一半的半殘文件而已。


樓主的意思好像是要保留狀態的熱更, 而不是nodemon這種無腦重起。 也就是所謂的Living Editing(注意不是livereload這種...), 這個我們這邊有同事在做相關的研究這個非常難。

回到正題,兩種方案實現樓主的需要:

1. 簡單的: 如果要熱更的模塊本身只暴露數據結構,

那沒有問題, 結合delete require.cache[filename] , 重新require就行 puer/rewrite.js at next · leeluolee/puer · GitHub .否則你要去推斷你這個模塊可能產生的邊際效應, 這個很難. 就比如在puer這個小工具中, 有個類似rewrite的配置

// use addon to mock http request
module.exports = {
// GET
"GET /v1/posts/:id": function(req, res, next){
// response json format
res.send({
title: "title changed",
content: "tow post hahahah"
})

},
// PUT POST DELETE is the same
"PUT /v1/posts/:id": function(){

},
"POST /v1/posts": function(){

},
"DELETE /v1/posts/:id": function(){

}
}

, 是可以熱更新的。 但是假如這段代碼是這樣的, 也可以達到這個效果, 但是你就需要去推斷這段腳本會引起router怎麼樣的內部狀態變化, 這個很難,你必須去看源碼才會清楚

router.get( /v1/posts/:id, fn1)
.post( /v1/posts/:id, fn1)
.....

-----

這樣描述可以好理解些: 你要保證這個模塊不會引入狀態, 才可以安全的進行熱更新

2. 複雜的: 第二種方式, 就是任意腳本的熱更新,這個從編程角度上無法解決的, 需要【運行時】的支持, 比如caspervonb/amok · GitHub 這個庫就利用了瀏覽器的控制台實現了living editing的效果。

當然如果我意會錯了題主的問題, 那remy/nodemon · GitHub就可以解決問題了 ,只是比常規node啟動多打了3個字元而已, 開發階段我平時也在用


可以實現熱部署,但是需要自己實現。通過刪除 module cache 然後重新 require 來實現,不複雜。


完全可以啊,require是動態的。


部署新代碼得重啟吧,不過用node自帶cluster模塊可以做到平滑重啟,期間對/index無影響,類似nginx平滑重啟,做到zero downtime。


第一你現在的程序結構有問題,如果在進程里進行緩存本身效率就低了,而且容易破壞http的無狀態處理。對於緩存強烈建議放在redis或者memcache這種地方。

如果基於上面那個結構,你大可以隨意的重啟服務了。本質上熱部署就是重新載入所有js文件的過程,只要速度夠夠快不必非要執著熱部署。如果想做到無縫切換,就複雜點了,需要在前面加上lvs之類的東西


在開發環境使用nodemon,在生產環境使用pm2

網上看到的。個人只用過nodemon.


難道你的緩存是存在一個全局的 Object 上???為什麼不用 Memcached 或 Redis?


推薦閱讀:

Mozilla Rhino 和 Node.js 兼容嗎?
應該使用 const 定義 object 和 array 嗎?
什麼是 GraphQL?
node.js和前端js有什麼區別?需要重新學習嗎?

TAG:Nodejs |