非同步匯入匯出架構設計
非同步匯入匯出架構設計
2018年04月27日 00:00:00 架構文摘 閱讀數:409
為什麼要用非同步?
在我們平時的業務系統中,檔案匯入,檔案匯出是一個很常見的業務需求。正常情況下,同步匯出就可以滿足我們80%的需求。但是對於資料量大,業務拼接複雜的系統來說,匯出超時,匯入超時是不可避免的,而且是無法忍受的。非同步能讓業務執行緒在後臺執行,沒有等待時間,處理完成通知出來就行了。這種場景在現實生活中也很常見,比如醫院裡面拍CT,做體檢時的體檢報告,都是延後去拿結果的。
非同步匯出的使用場景
那什麼時候會需要用到非同步呢?統計、匯入、匯出、傳送模板訊息、訂單狀態變更後的複雜業務處理。
它們都有共同的特點:
1. 處理耗時長
2. 業務優先順序低
3. 容易超時
4. 資料量大
檔案匯出
非同步匯出的優缺點
-
非同步的優點:
它能解決匯出超時問題,能大大的提高介面請求處理速度,提高吞吐量,提升系統性能
任何事情都有兩面性,也許不具有絕對性,但是在這裡是成立的。既然它有那麼多優點,當然也會有缺點。
-
非同步的缺點:
它比同步匯出要複雜得多,介面多了幾倍,所需伺服器也要多,學習成本高,開發成本高
架構圖設計
架構解析
按流程來:
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, {})
}
專案實際應用
點選取消後
非同步匯出的整個流程和設計就全在這裡了。
檔案匯入的設計
由於篇幅有限,且匯入的流程大同小異。直接奉上一副設計圖吧。
多級非同步匯入方案
最後
程式碼是沒有滴,東西是要自己創造滴!
補充
一些人說需要貼程式碼,但這個是涉及3個伺服器的協作,(前端伺服器,node層web伺服器,純後端介面伺服器),程式碼太過於零散且沒有多餘的技術含量,無法貼上來,加上這套機制我在C#大型電商專案和java的多個專案中都有部署應用。對於不同語言有不同的實現。就目前來說,在電商專案中穩定運行了一年多,它的可靠性已經得到了實際應用的考驗。
伺服器需求
組成這套系統最少要求(web伺服器一臺,介面伺服器一臺,redis伺服器一臺,檔案伺服器一臺)
如果在java體系裡面,前後端完全分離,且有伺服器資源充足的情況下
前端伺服器
node層伺服器(叢集)
後端介面層伺服器(叢集)
redis伺服器
檔案伺服器
架構定位
對於小公司來說,伺服器資源沒有那麼充足,可能實施起來有難度,且開發和學習成功較高
對於大型公司來說,對於大資料量和複雜業務的匯出,可能早就有了成熟穩定的框架來支援,例如任務中心這種完善的非同步訊息來實現,具有高可用,可伸縮的等穩定性很強的系統,也用不到了,
因此這套架構適合於中型規模的公司
各層級職責解析
node或者web
出處:http://www.cnblogs.com/jingch/p/8832161.html
版權申明:內容來源網路,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝。