歡迎光臨
每天分享高質量文章

前後端分離專案實踐分析

作者:全棧工程的博客

網址:http://segmentfault.com/a/1190000002978095


一、前言

對nodejs有了些準備,希望多瞭解些後端知識,恰逢公司專案調整,分析了前後端分離的優劣,也做了一個完整的demo演示,同事都覺得靠譜,用了兩個版本的時間,將公司主站專案用nodejs實現了前後端分離,在此和大家分享下,以求共同進步。案例參見 http://www.upopen.cn

二、為何做分離

1、開發體系:架構體系決定了後端重於前端,前端做好靜態頁後,要轉為php或vm等,開發要用eclipce等後端環境工作,一大堆讓前端迷糊的配置,一旦java人員更新了錯誤的檔案,會導致所有人的環境啟動不了,束手無策,只能等待救援。

2、難維護:頁面總是會有php\jsp等非前端代碼,相互干擾、無法優化,時間越久問題越突出。

3、前後端職責不清晰。

有人會問,分離為什麼不全部走ajax,頁面就不需要任何服務端語言了。但實際場景並非如此,首先有些資料總是要生成頁面時就已經同步獲取的,且全異步對SEO不利、純html頁面沒有include功能等。

網上還有其它的理解,大致相同就不列舉了。

三、如何做分離

1、產品設計確定後,前後端人員共同制定開發接口,為方便接口的制定、顯示、測試,使用nodejs+mongodb開發了接口平臺。參見http://www.upopen.cn:8090/interface/index

功能:制定接口時就直接在interface平臺上新增錄入ActionName、description、 method、 param 及 預設值 等並儲存到mongodb,當後臺開發完成後,直接用在該頁面做接口測試,成功後方可交付,避免聯調過程中的接口反覆。(原本想用interface.upopen.cn 來測試同域名下的專案,但因cookie在不同二級域名下無法共享的問題,暫用了二級目錄,不過已有方案,後續優化)

2、從前端角度考慮系統架構圖如下:

前後端分離架構圖

  • 訪問入口 NGINX 代理靜態資源到 STATIC 服務器,其它請求則到 NODEJS。
  • 頁面請求NODEJS直接render,資料相關NODEJS則做預處理,再發到後臺
  • 前端據已定義的接口,通過nodejs+mysql模擬後臺完成資料存取,此處會增加些工作量,但只是為了走通業務流程,模擬後臺資料表定義及邏輯無需嚴謹,只要能正常存取即可,如註冊用戶save to DB,登錄驗證read from DB,所以提供樣式化的工具、寫法後,新增表、接口,並不會多耗時間,nginx – nodejs – 模擬後臺,即可按實際使用完成所有前端工作。
  • QA單獨測前端時,修改hostIP指向到測試工具。
  • Java開發完成後接口,在 Interface平臺 上驗證所有接口,確認無誤。QA也可以通過Interface測試Java接口
  • nodejs修改config里的hostIP配置到java,理想情況下,修改此步配置即完成聯調

每個模塊的簡略部署如下:

Nginx.conf:

Location ~ \.(jpg|png|css|js ){ //靜態資源代理

Root /root/static/;

}

Location \{ //其它接口轉發

Proxy_pass http://upopen.cn;

}

Upsteam upopen.cn{

Server http://node.upopen.cn;

}

STATIC 結構如下:使用require.js做模塊化加載工具,有朋友問為什麼不用seajs,還問這兩個優劣,其實前兩年的專案用的都是seajs,此處想試試amd vs cmd,所以就用了require.js ,以目前的使用來看,相互可替代

Core:[核心模塊,主要是引入第三方必用、穩定模塊]

Base.js [自定義通用函式]

Require.js

Jquery.js

Bootstrap.js

Backgone.js

Socket.io.js

I18n.js

Public: [業務級公共模塊]

Validate.js [表單驗證模塊]

All.js [所有頁面需要執行的業務js,如登錄驗證]

Zhdoc.js [國際化文本定義]

Reset.css [樣式初始化]

common.css

Widget: [自定義組件]

Dialog: [彈框組件]

Dialog.js

Dislog.css

Imgs: [彈框組件圖片]

Calendar:[日誌組件]

Calendar.js

Calendar.css

Imgs: [日曆組件圖片]

Module: [業務模塊]

Issue: [靜態模塊]

Index: [首頁]

Index.js

Index.css

Imgs:

news: [新聞]

news.js

news.css

imgs:

User: [用戶模塊]

Register: [註冊]

Register.js

Register.css

Imgs:

findPwd: [找回密碼]

findPwd.js

findPwd.css

imgs:

Nodejs結構主要如下: express 框架

App.js

Package.json

Node_modules:

Routes:

Index.js – 路由入口,接收所有請求做轉發,並做權限過濾、404等

Issue.js – 接收來自index.js的靜態請求

User.js – 接收來自index.js的用戶請求,頁面請求render,資料請求轉發

Views: [使用ejs框架,接收來自 routes 里的頁面請求]

Common: [公用模塊頁]

Header.ejs

Footer.ejs

Issue: [靜態模塊頁]

Index.ejs

News.ejs

User: [用戶模塊頁]

Register.ejs

findPwd.ejs

Controls: [業務邏輯模塊]

Config.js –公共配置模塊,如hostIP、basePath等,切換環境修改此配置

User.js – 接收來自 route/user.js的資料請求,向外轉發做邏輯準備

Tool.js – 封裝常用函式如http.request/mailer/md5等

Redis.js – redis封裝,對於單體封裝內容比較多的模塊,單獨成立一個檔案

Log: [日誌,採用Log4js,日誌是必須的,頁面開發者常欠缺日誌理念]

Assets: 結構、使用同 STATIC,不配置nginx時,呼叫此處資源,意義不大

Nodejs + MySql: [模擬後臺模塊,相對上面的模塊,主要多了DB]

Db: [資料處理模塊]

Mysql.js – 封裝樣式化資料儲存接口,提供最便捷的新增表、接口的方法

按此結構完成前端所有功能,因目前專案較小,部分模塊還有細分空間。

四、分離結果如何

1、開發效率更高,在聯調之前,互不干擾,前端開發完成後就是實際可用的代碼,不需要再轉換成後臺編譯環境,永遠不會被java / php 啟動不成功所困擾。

2、部分需要前後端共同開發的功能,如檔案上傳,通常需要頁面端與接收端都進行相關的開發配置,之前較難定位是誰配置錯誤,現在全部由前端完成,開發、測試都容易定位,上傳成功後,只要向java發送檔案儲存的路徑即可。

3、完全分清了前後端開發人員的職責,任一方開發完成後都可以提測,實現同步開發、測試。

4、聯調非常簡單,若雙方接口一致,正常情況下只要修改要接口請求IP即可完成切換。

5、問題責任清晰,聯調、測試、預發、上線,每個過程都難免會產生問題,前端、後端、運維三方責任邊界清晰,日誌中記錄nodejs的請求發出,nginx請求接收與轉發、java端請求接收與傳回,三處任何一處斷點,都能馬上定位是哪方的問題。

6、前端人員有更高的權限,頁面端的展示幾乎全由前端實現,但之前一些配置卻受制於後臺,比如常見的模板功能,純html頁面雖可以通過angularjs實現模板,但實際效果卻並不理想,網速差時經常會出現include部分顯示後置、甚至加載不成功的情況,nodejs的ejs框架可以很好的實現這個功能。

另外,據瀏覽器加載不同的css以便實現瀏覽器兼容,之前處理通常是頁面加載後,通過js判斷瀏覽器型別,再去加載不同的css檔案,影響渲染效率,並且js判斷瀏覽器型別本身就存在兼容問題,用nodejs則可以在render前就完成該判斷,直接用相應的瀏覽器樣式做渲染

7、代碼復用,驗證模塊,頁面端與nodejs端可以直接復用

五、註意事項:

1、前端開發人員不僅需要有扎實的nodejs知識,還要有一定的服務端、運維知識,對http通信有更深層次的理解,nginx、redis、socket、buffer等技術也要掌握,多多益善。

2、開發之初對功能充分、寬裕的評估,使用初期不要用nodejs過多開發新功能。初次使用,難免會遇到很多意想不同的問題,前端開發人員本身對服務端知識有限,java人員又對nodejs語法不熟,若處理不好會導致專案延期。我原本認為redis同memcached一樣就是connect + set + get,但實際開發時遇到一些考慮不周而產生的怪異問題,延長該部分開發時間,最終導致專案delay。

3、前端開發人員可嘗試用linux系統開發,第一版用win7開發時,npm部分模塊的安裝會不順利,如node-canvas在win7上安裝需要6步,而原本在32上已配置成功了,在64位上的系統上又不成功,後來該接口暫由java實現。實際上即使配置成功了,該模塊在發佈服務器的linux系統上也無法使用,需要重新安裝。第二版開發時,我使用了ubuntu,雖然有一定的學習成本,但對後期的效率提升十分有益,多學習一種系統操作,和運維除錯時也更加主動。不過ubuntu下沒有找到做PSD切圖的工具,所以安裝雙系統更合適切換使用。

六、總結:

目前用分離方式做了兩版專案,開發效率提升、協作溝通便捷上有明顯優勢,作為前端也學習了很多新知識、擴大影響範圍,是共贏的。目前使用還較初級,要繼續學習、探索。在此貼出以便和同仁共進步之。

赞(0)

分享創造快樂