異步導入導出架構設計

 

爲何要用異步?

在咱們平時的業務系統中,文件導入,文件導出是一個很常見的業務需求。正常狀況下,同步導出就能夠知足咱們80%的需求。可是對於數據量大,業務拼接複雜的系統來講,導出超時,導入超時是不可避免的,並且是沒法忍受的。異步能讓業務線程在後臺運行,沒有等待時間,處理完成通知出來就好了。這種場景在現實生活中也很常見,好比醫院裏面拍CT,作體檢時的體檢報告,都是延後去拿結果的。前端

異步導出的使用場景

那何時會須要用到異步呢?統計、導入、導出、發送模板消息、訂單狀態變動後的複雜業務處理。。。 java

它們都有共同的特色:node

1.處理耗時長web

2.業務優先級低ajax

3.容易超時redis

4.數據量大後端

文件導出

異步導出的優缺點

異步的優勢:api

      它能解決導出超時問題,能大大的提升接口請求處理速度,提升吞吐量,提高系統性能服務器

任何事情都有兩面性,也許不具備絕對性,可是在這裏是成立的。既然它有那麼多優勢,固然也會有缺點。架構

異步的缺點:

     它比同步導出要複雜得多,接口多了幾倍,所需服務器也要多,學習成本高,開發成本高

架構圖設計

 

 

架構解析

按流程來:

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分鐘後任務將放棄,用戶能夠再次點擊導出按鈕。

數據來源

 

接口設計

 接口列表

 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, {})
}

 

項目實際應用

 

 點擊取消後

 

 

 

異步導出的整個流程和設計就全在這裏了。

文件導入的設計

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

多級異步導入方案

 

 

最後

代碼是沒有滴,東西是要本身創造滴!

--------------------------------------------------神祕的分界線---------------------------------------------------

2018-04-15補充

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

 

服務器需求

組成這套系統最少要求(web服務器一臺,接口服務器一臺,redis服務器一臺,文件服務器一臺)

若是在java體系裏面,先後端徹底分離,且有服務器資源充足的狀況下

前端服務器

node層服務器(集羣)

後端接口層服務器(集羣)

redis服務器

文件服務器

 

架構定位

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

對於大型公司來講,對於大數據量和複雜業務的導出,可能早就有了成熟穩定的框架來支持,例如任務中心這種完善的異步消息來實現,具備高可用,可伸縮的等穩定性很強的系統,也用不到了,

所以這套架構適合於中型規模的公司

 

各層級職責解析

 

node或者web

 

若是有疑問能夠找我解答。

相關文章
相關標籤/搜索