1. 程式人生 > >非同步匯入匯出架構設計

非同步匯入匯出架構設計

非同步匯入匯出架構設計

2018年04月27日 00:00:00 架構文摘 閱讀數:409

為什麼要用非同步?

 

在我們平時的業務系統中,檔案匯入,檔案匯出是一個很常見的業務需求。正常情況下,同步匯出就可以滿足我們80%的需求。但是對於資料量大,業務拼接複雜的系統來說,匯出超時,匯入超時是不可避免的,而且是無法忍受的。非同步能讓業務執行緒在後臺執行,沒有等待時間,處理完成通知出來就行了。這種場景在現實生活中也很常見,比如醫院裡面拍CT,做體檢時的體檢報告,都是延後去拿結果的。

 

非同步匯出的使用場景

 

那什麼時候會需要用到非同步呢?統計、匯入、匯出、傳送模板訊息、訂單狀態變更後的複雜業務處理。

 

它們都有共同的特點:

 

1. 處理耗時長

2. 業務優先順序低

3. 容易超時

4. 資料量大

 

檔案匯出

 

非同步匯出的優缺點

 

  • 非同步的優點:

 

它能解決匯出超時問題,能大大的提高介面請求處理速度,提高吞吐量,提升系統性能

任何事情都有兩面性,也許不具有絕對性,但是在這裡是成立的。既然它有那麼多優點,當然也會有缺點。

 

  • 非同步的缺點:

 

它比同步匯出要複雜得多,介面多了幾倍,所需伺服器也要多,學習成本高,開發成本高

 

架構圖設計

640?wx_fmt=png

架構解析

 

按流程來:

 

1. 前端發出匯出請求

2. 介面伺服器接到請求並校驗引數

3. 如果引數不符,直接彈出校驗結果,流程結束!

4. 生成一個任務實體,狀態設為處理中並將實體寫入redis。開啟非同步執行緒,在非同步方法中呼叫匯出介面。返回給前端在處理中狀態

5. 前端接受到已經在處理中返回值,開啟ajax輪詢,每隔10秒請求一次任務查詢狀態介面

6. 匯出介面將資料拼接完成

7. 將資料傳到檔案伺服器生成檔案並返回url

8. 從redis中取出任務實體將url寫入,並且將狀態設為已完成並更新redis(後端處理流程就結束了)

9. 前端ajax請求發現返回值狀態變成已完成後,取出url並停止輪詢。

10. 前端請求清除任務實體介面,通過後端介面將redis中的物件移除。

11. 前端展示匯出結果,自動下載或者手動點選可以根據業務來。

 

這裡還有一個頁面初始化的按鈕變化流程。

 

1. 開啟頁面後匯出按鈕置灰不可點選

2. ajax請求查詢任務狀態介面,如果顯示沒有任務在進行中,那就讓匯出按鈕可以點選。如果狀態是匯出已完成,則顯示下載按鈕相關頁面

 

另外,為了防止意外出現redis死鎖的情況,導致客戶一直用不了匯出功能,每個任務redis物件都有過期時間,設定為30分鐘。也就是說,不管匯出任務執行是否完成,30分鐘後任務將放棄,使用者可以再次點選匯出按鈕。

 

資料來源

640?wx_fmt=png

介面設計

 

介面列表

 

1. 獲取任務狀態 getTaskStatus     

              返回實體TaskResultOut:

 

欄位 l型別 是否可為空 註釋
status
 int  不,預設0  任務狀態(0=未開始,1=進行中 2=已完成)
   message  string  是  提示資訊(正確或錯誤)
   url  string  是  檔案地址
   state  bool  不,預設fasle  任務成功還是失敗(y)

 

2. 註冊匯出任務(匯出) registerExportTask

          返回true/false,表明是否註冊成功

 

3. 清除任務狀態 clearTaskInfo

          返回true/fasle,表明清除是否成功

 

前端設計

 

前端js由前端編寫,具體的由於巢狀太深,就不貼出來了,在架構解析中已經說的很詳細了。

 

"export": function(e) {
return t.post(r.api.form["export"], e, {})
},
getTaskStatus: function(e) {
return t.post(r.api.form.getTaskStatus, e, {})
},
registerExportTask: function(e) {
return t.post(r.api.form.registerExportTask, e, {})
},
clearTaskInfo: function(e) {
return t.post(r.api.form.clearTaskInfo, e, {})
}

 

專案實際應用

640?wx_fmt=png

 

640?wx_fmt=png

 

 點選取消後

 

640?wx_fmt=png

 

 

 640?wx_fmt=png

非同步匯出的整個流程和設計就全在這裡了。

 

檔案匯入的設計

 

由於篇幅有限,且匯入的流程大同小異。直接奉上一副設計圖吧。

 

多級非同步匯入方案

 640?wx_fmt=png

最後

 

程式碼是沒有滴,東西是要自己創造滴!

 

補充

 

一些人說需要貼程式碼,但這個是涉及3個伺服器的協作,(前端伺服器,node層web伺服器,純後端介面伺服器),程式碼太過於零散且沒有多餘的技術含量,無法貼上來,加上這套機制我在C#大型電商專案和java的多個專案中都有部署應用。對於不同語言有不同的實現。就目前來說,在電商專案中穩定運行了一年多,它的可靠性已經得到了實際應用的考驗。

 

伺服器需求

 

組成這套系統最少要求(web伺服器一臺,介面伺服器一臺,redis伺服器一臺,檔案伺服器一臺)

 

如果在java體系裡面,前後端完全分離,且有伺服器資源充足的情況下

 

前端伺服器

 

node層伺服器(叢集)

 

後端介面層伺服器(叢集)

 

redis伺服器

 

檔案伺服器

 

架構定位

 

對於小公司來說,伺服器資源沒有那麼充足,可能實施起來有難度,且開發和學習成功較高

 

對於大型公司來說,對於大資料量和複雜業務的匯出,可能早就有了成熟穩定的框架來支援,例如任務中心這種完善的非同步訊息來實現,具有高可用,可伸縮的等穩定性很強的系統,也用不到了,

 

因此這套架構適合於中型規模的公司

 

各層級職責解析

 

640?wx_fmt=png

node或者web

 

640?wx_fmt=png

 

出處:http://www.cnblogs.com/jingch/p/8832161.html

 

版權申明:內容來源網路,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝。