1. 程式人生 > >由React引發的前後端分離架構的思考

由React引發的前後端分離架構的思考

outer java 模塊 qps ESS etc 降級 red 器)

摘要

以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測試。

前後端分離的價值

敏捷、快速響應、提升效率,專業化的分工和協作、提升專業度和研發效率,結構清晰,降低維護成本,前後端各自獨立擴展、自由水平伸縮。

未來可期

現在我們需要考慮下之後還有那些需要加強的地方,比如說服務網關、安全與運維特性的增強,公共組件的進一步提煉與封裝,性能與體驗的提升,框架開源等等。

今天的分享就到這裏,謝謝大家!

編者:IT大咖說

由React引發的前後端分離架構的思考