本文從業務場景來談談爲何選擇Node,以及前端寫後端代碼須要補足的短板。php
這些日子一直在作Node方面的嘗試,或多或少會收到周圍的異樣的目光甚至背後的質疑,因而促使我好好思考爲何我在作Node。網上搜下「爲何要用Node」,找到的文章多數是介紹Node多麼多麼牛逼,無非是從Node自己特性來講,好比:併發、事件驅動、非阻塞I/O、單線程、流、社區生態……諸如此類,不多談業務場景。
我是「實用主義」者,說過:脫離業務場景談架構都是耍流氓。由於我的是從一線業務作起的,通過幾年對業務的思考,我以爲能夠從業務場景來講說爲何咱們的業務更適合用Node。前端
如今咱們的業務模塊化愈來愈廣泛,不多有業務比較純粹只有連接一個數據庫就能夠搞定,每每前臺業務後面會有N多的API服務作支撐。好比:下面兩種狀況在咱們實際開發中常常碰見:node
上面兩種狀況,站在後臺開發的角度來看,咱們業務模塊要分開要獨立,而站在前端的角度來看,這些數據都是一個頁面須要的,前端但願是一個接口給我返回。這是一個開始。。nginx
固然後臺開發,好比PHP也有併發請求的解決方案,好(上)心的後臺工程師,會幫助在後臺統一合併請求處理成一份數據或者接口,而後扔給頁面使用。好比在實際開發中,咱們的前端會寫(而且維護)一個Template.class.php
(我敢說咱們80%的後臺工程師都沒看過這個代碼。。),在View層使用,而後在Action當中將數據傳給View層作渲染,下面的代碼:git
$this->render('xxx/xx.tpl', $tplData);複製代碼
這樣增長的溝通成本,下降了開發效率。爲了一個頁面,須要前端根據頁面想要的數據,和後臺溝通頁面的數據格式,而後後臺工程師找他們後面的API模塊要數據、處理數據。這個過程當中會有一些「灰色地帶」,很差明確誰作更合適,徹底靠自覺。github
每每開發的時候會想各類方法來解耦,好比:引入後臺模板(smarty之類),而後約定數據格式,前端根據數據格式來寫Mock接口,寫後臺模板的前端就叫「大前端」;再Low一點的團隊,會採起前端作好頁面扔給後臺工程師「套頁面」,好比:PHP代碼寫HTML,各類<?php echo xxx;?>
,代碼很不友好,後臺工程師幸福感也急劇降低。web
還有一種作法是,乾脆後臺淪爲「代理服務器」,收到請求我轉給後面的API,拿到數據我返回給前端頁面,作成能夠「跨域」的接口,因此就成了好多webapp。數據庫
另外,站在後臺工程師的我的發展來看,可能他們以爲:這些「包接口」的重複性工做,跟本身的晉升和技術發展又有毛線關係呢?後端
說道這裏,確定有人內心在嘀咕:這是大家大公司纔有的問題,咱們小公司不會有這樣的問題!那我下面再從技術方面來講。跨域
從性能優化、工程化、解決方案這三個開發中最最多見的方面來講明爲何前端的事情前端作更合適。
前端頁面是重要的載體,出現問題或者頁面體驗很差會對用戶形成直接的傷害(咱們都是背鍋俠)。頁面性能這些問題顯然是前端的頭等大事,可是這些事情跟後臺工程師關係多大呢?當你發現該優化的項目都優化完了,剩下的優化項目就須要跟後臺工程師一塊兒優化了,而這時候再去push後臺工程師一塊兒參與前端優化項目。
除了前端頁面的性能優化這種項目,還會有一些工程化的工做,幫助提升前端的開發效率和體驗,但實際上只有前端是搞不定的,好比:
這些工程化的工做自己前端本身理解的很清楚,可是後臺工程師會有多少了解呢?怎麼不可能讓對前端不瞭解的後臺工程師參與進來呢?解釋要作什麼就花費很多時間。
再說解決方案,簡單點若是咱們要實現頁面chunked輸出,將動態和靜態數據分開,不依賴接口數據的數據首先展示(好比首屏的Nav),那麼也要依賴後臺工程師的代碼。再大一點,咱們上個相似Bigpipe的方案,那麼對後臺的依賴和改造更大。
上面的這些訴求,有兩種方案:前端本身擼袖子來搞,他們或者是直接寫相似PHP來實現,或者是寫不三不四的Smarty擴展代碼;再者就是能夠出一個「技術產品經理」,專門立項來搞這些項目,由「技術產品經理」來協調兩邊需求,避免「雞同鴨講」。但是業務部門項目壓力是很是大的,不多有這樣的項目,而專門作技術的團隊呢,又很難深刻業務,每每高高在上,搞出來的東西要麼不合實際、要麼過高新尖端,致使水土不服,強推起來,業務團隊哀聲哉道。我也說過:脫離業務的架構都是耍流氓。。
根據上面說的,大概得出使用Node有下面的好處:
同時,大概得出什麼樣子的業務場景使用Node:
當談到「咱們要用Node」,每每會遭到以下具體的質疑(注意是具體,不是純懟):
先說這些前面三個問題:
後面兩個問題主要是跟公司運維能力有關係:
因此咱們廠子內部已經爲Node大規模使用在流程和運維方面已經作好了準備。
最後說下Node生態問題,Node版本的確升級很快,可是隻關注LTS版本,等發版一段時間以後跟進更新便可,目前百度內部的Node Runtime是6.10版本,據說很快就要生7.0了。對於框架和業務代碼用到的NPM包,徹底能夠作版本指定,也能夠作自動測試,跑過了case則提交進master,隨着下個版本回歸上線。
無論怎樣,咱們用Node已經變得瓜熟蒂落,可是咱們也要知道本身的不足,拓寬本身的視野。
首先是後臺思想,在前端開發中,咱們的代碼是跑在每一個用戶本身的瀏覽器裏面,代碼之間是隔離的,因此無論你代碼寫的好壞,只要是說的過去,就不會有大的問題,好比:偶爾內存泄漏一下,彷佛也影響不大。可是server的代碼是長久執行下去的,不是用戶走了就釋放的,因此一個小的內存泄漏,長時間下去也會引發大的問題。再好比:瀏覽器的JS你能夠偶爾使用個全局變量(少寫個var),可是若是在Node的代碼,將用戶相關的個性數據放在global
,那麼當下個請求過來,而代碼尚未處理完當前請求,會致使本身用的數據不是當前用戶的,碰到這種問題,只能把個性化的數據一層層的傳下去。還有缺少優化意識或者過分優化,該用緩存的時候不用,不應用的時候亂用。
再舉個case,看下面的代碼:
module.exports = function (ip) {
var ipfinder = require('ipfinder');
ipfinder.loadData('ip.data');
return ipfinder.findSync(ip);
}複製代碼
這個是數據實時分析項目的一段相似的代碼,ipfinder是我寫的一個IP查找庫,ipfinder.loadData('ip.data’);
會引入一個二進制的ip數據庫,這個比較消耗資源,寫在module.exports
是沒有必要的,每次執行module都加載一遍,很費資源,拿到module.exports
以外,程序的CPU從99%降到了5%....
第二個是安全意識,以前在「Vue項目重構」中提到proxy.js
的代碼弊端,就是缺少安全意識致使的。前端寫後臺程序,由於缺少安全意識,每每在接口設計、頁面片斷拼接等方面犯錯誤,好比:接口設計的過於簡單,缺少校驗,容易致使CSRF攻擊,若是有數據庫操做,手動拼接SQL語句容易致使SQL注入。
最後是運維知識,前端工程師寫Node服務,就不在簡單的對瀏覽器負責,而還應該對服務器負責,服務器的穩定性、各類監控指標都應該有所瞭解,對於機房配置、資源調配、運維架構、服務架構都應該了熟於心,避免出現線上事故了本身還不知道從哪裏排查的窘態。
固然你可能會說,剛剛開始接觸是能夠容許犯錯的,可是要知道: 技術的調整是不該該損害產品服務的。以上三點內容須要剛剛轉Node開發的前端工程師注意增強學習,能力越大責任越大!開始時候可能會犯錯和抓瞎,該請教就請教,時間長了可以點亮新的技能點~
@三水清
未經容許,請勿轉載。
感受有用,歡迎關注個人公衆號