內容來源:2017年7月22日,浪潮國際金融產品技術架構師丁周芳在“【濟南】OSC源創會第65期”進行《一場由React引發的前後端分離架構的思考與實踐》演講分享。IT 大咖說(微信id:itdakashuo)作為獨家視訊合作方,經主辦方和講者審閱授權釋出。
閱讀字數:2715 | 7分鐘閱讀
摘要
以React技術棧為主分享我們在大規模企業應用建設過程中遇到的問題,對前後端分離架構的思考,前後端分離的技術方案,前後端分離過程中的實踐經驗,前後端分離帶來的效果與價值,以及目前存在的問題與未來可能的嘗試。
應用的現狀
我們的應用擁有接近100w的使用者、3K+的QPS、5億+的單表資料、萬億級別的資金流,但是同樣也面臨著諸多問題。
首先是顏值低,換膚受限、無法整合更好的前端框架和元件。然後是前後端的高度耦合使得無法快速的響應業務變化,維護成本也隨著應用規模不斷攀升,效能方面也受到限制,溝通成本提高。其次是無法跨終端,渲染和跳轉強依賴於後端,業務邏輯分散。最後就是強狀態性,應用中很多的資料是與使用者的會話綁死的,由此造成沒有水平伸縮的能力,智慧化、自動化、服務化同樣受限。
我們經過思考認為理想的狀態應該是這樣的,前端方面具備高顏值、個性化、多渠道、多終端的特質;而在後端上需要能做到微服務化、水平伸縮、高可用、自動化甚至智慧化。
解決方案-前後端分離
定義
在之前的應用中後端是Java,前端是Browser(瀏覽器)。但是現在Node出現了,它被包含在大前端中用來替換原來的MVC部分,這樣後端就可以脫離出來處理純服務化的部分,前端也可以專注於純前臺的領域。
各自的職責
前端方面Browser負責資料的展現和收集、事件的響應和處理、DOM的操作、請求的傳送和響應的處理。Node用來處理之前通過後端來實現的頁面渲染、跳轉和資料的傳遞等功能。而後端方面則專注於業務邏輯的封裝、服務介面的提供以及序列化。
總體的方案
從總體上來看前端和後端基於服務化的方式進行互動,通過Json進行資料傳遞。前端做到元件化、後端實現模組化。
前端的選擇
在嘗試了很多方案後,我們選擇了React+Redux,因為在React上有一定技術積累,同時國內也有很多的成功案例。但是由於Redux太靈活了,在接觸了三週後我們選擇了放棄,轉而使用螞蟻金服開源的基於React的一款展示框架AntD和基於Redux封裝的Dva框架。
前端的技術架構
當有一個請求過來後,會通過Component或Route來展示介面。同時也會接收使用者的點選事件,每一個點選事件都會由dispath來觸發一個Action,這之後會產生兩種結果。
一種是直接通過reducers函式改變狀態state,使與前臺關聯的model發生變化,由此來改變前臺頁面。另一種是呼叫後臺的服務,通過fetch進行後端服務的訪問,後臺服務返回的資料會由effects函式處理,處理後會交給reducers函式去改變狀態state,進而觸發前端的元件重新整理和渲染。
最後還有一個subscriptions函式是進行前端攔截的,當攔截到一個URL請求之後仍然是觸發一個Action,然後又會導致上面的兩種變更。
後臺的技術架構
後臺的邏輯就相對複雜了,我們採用了分層的技術架構。最底層是基礎設施,支援公有云、私有云當然還有本地伺服器。然後技術平臺層就是一般常見的架構,囊括一些系統許可權、工作流、開發框架之類的。基於之上的是通用的服務層,裡面有一些報表服務、列印服務,單據服務等。再向上就是業務模組的部分,包含賬戶管理、任務管理、自助中心等。最後頂層的就是介面服務層了,它是基於Web Service和Restful Service的。
除了上面的主體框架外,我們還有服務閘道器模組,主要是用來做流量控制、安全監控、負載均衡、服務降級與熔斷等。另外就是安全運維模組,用來處理身份認證、訪問控制、加密解密,審計日誌,運維工具等等。
實踐經驗
前後臺互動
目前絕大部分業務表單資料與後臺的互動都是使用Fetch方式。另外由於一些遺留系統的問題仍然保留著AJAX方式,並對他進行了一些改進。而檔案類的操作比如上傳、下載,這些目前使用的是Form提交的方式。
跨域
我們原來是通過Jsonp來解決的,但是Jsonp的問題是隻能支援get請求,引數會被暴露出去。出於安全性的考慮我們選擇了目前主流的CORS方式,只在服務端處理跨域不涉及到客戶端。
應有無狀態
應用的強狀態性是由於過度依賴會話造成的。會話的原理其實就是在Session中儲存了一些資料,此時Session被當做快取來使用;還有一個重要的職責是維護與客戶端的聯絡,讓後端可以判斷是哪個客戶端傳送的請求。而現在我們採用Token來識別客戶端,快取的職責使用分散式cache來代替。
頁面的跳轉和引數傳遞
原先被放在後端通過forward或redirect的跳轉、引數傳遞,現在被前端的Router代替,資料傳遞通過PayLoad進行。而如果需要依賴後端的一個狀態才能進行跳轉,那麼只需要從後臺獲取一個訊息,前端會根據這個訊息來判斷跳轉的走向即可。
錯誤處理
我們的經驗是後端統一異常錯誤捕獲,然後進行分類,通過異常錯誤資訊字典來統一向前臺反饋錯誤資訊。前臺從後臺得到錯誤的資訊後,以此進行前端介面的提示和跳轉到錯誤頁面。
安全
通過Token來進行身份的驗證,另外為防止Token一直有效,當前臺主動登出時會登出Token;同時後臺也會根據配置的回話過期時間來自動登出不活動的回話。訊息的加解密,系統的訪問控制,包括系統功能許可權與資料許可權也會有專門的服務。
質量的保證
原來的統一測試被分開了,前後端先分別獨立mock資料進行單元測試,然後是聯調測試,聯調測試完後再根據測試用例進行冒煙測試。冒煙測試完成後開發人員的測試算是完了,後續就交由專業的測試人員來進行整合測試,UAT測試。
前後端分離的價值
敏捷、快速響應、提升效率,專業化的分工和協作、提升專業度和研發效率,結構清晰,降低維護成本,前後端各自獨立擴充套件、自由水平伸縮。
未來可期
現在我們需要考慮下之後還有那些需要加強的地方,比如說服務閘道器、安全與運維特性的增強,公共元件的進一步提煉與封裝,效能與體驗的提升,框架開源等等。
今天的分享就到這裡,謝謝大家!