開發:你確定這個玩意有實現的必要?
產品:當然,需求就是這樣的
開發:但是對方介面的響應時間太長了吧,而且是兩個
產品:嗯,我跟對方確認過的,第乙個介面的響應時間是12s左右,第二個介面的響應時間是40s左右,並且呼叫第二個介面還需要在第乙個介面的返回基礎之上
開發:那還有做的必要嗎?這個使用者體驗得差到什麼程度,要是長連線伺服器得爆掉,要是定時請求,伺服器也承受不住啊
產品:這個是公司的乙個試探性產品,主要是為了探索市場,產品體驗差沒關係,不過這兩個介面和銜接的流程你得好好設計一下,因為這兩個介面這條產品線會一直使用
開發:目瞪口呆?
為了探索市場,產品需要快速開發乙個產品,該產品需要呼叫第三方兩個介面,但是這兩個介面的響應時間真不好意思說(作者高度懷疑第三方的伺服器架設在火星上),更坑的是使用者輸入內容需要順序呼叫這兩個介面,呼叫第二個介面需要根據第乙個介面返回的內容,最坑的是,這個流程可能會成為這條產品線的主要流程,所以需要好好設計一下,保證服務的可用性,一圖以畢之:
對,整個介面的響應時間大約需要52s,就問你坑不坑,而且產品居然能夠根據這兩個介面設計產品,小弟在這裡已經跪下了。
雖然產品很坑,雖然第三方很坑,雖然介面非常坑,但是我們是誰,我們是程式猿,就算這個世界都在坑,我們也會是最穩的,基於上面介面響應的現狀,以及前端原因,無法進行push,那麼定時pull成為了更好的選擇,
流程如下:
1:前端呼叫介面,開始主業務,主頁返回執行中資訊,並且開啟非同步方法,非同步方法呼叫統一的出口服務,出口服務呼叫第三方
2:非同步方法根據第乙個介面返回結果呼叫第二個介面,進行**計算,經過漫長的40s等待之後,返回結果
3:前端一直定時請求該介面,根據使用者id獲取執行結果,一旦執行完成,那麼同樣通過該介面獲取返回結果
缺點:1:主業務服務呼叫對外介面服務等待時間過長,我們都知道微服務體系中服務之間的呼叫會設定超時時間,這裡的介面呼叫時間過長,一定會出現超時,致命坑
2:主業務開啟了非同步執行緒,但是非同步執行緒一直處於等待狀態,出現了多餘執行緒消耗情況,坑
3:前端反覆呼叫同乙個介面,業務和非同步執行結果混雜,未進行解耦,坑
4:非同步方法發生異常,未執行完成,前端會一直等待狀態,太坑了
5:使用者如果多次觸發該業務,那麼每次都需要進行完整的業務,時間太長,使用者體驗差,太坑了
結論:這是一版失敗的設計,未考慮清楚介面的超時帶來的影響,同時也未處理業務和非同步解耦
既然第一版有缺陷,那麼針對第一版的缺陷進行了第二版的設計
流程如下:
1:前端呼叫主業務服務介面,主業務方法根據需要開啟了非同步處理,首先在非同步服務中進行了非同步流程註冊,非同步服務返回乙個唯一的非同步執行id,介面直接返回了前端非同步id和執行狀態碼,告訴前端,現在已經開啟了非同步流程,需要查詢結果,請到非同步服務中
2:主業務服務介面開啟非同步方法,呼叫對外介面服務進行第一次資訊查詢,並且就查詢結果存入快取,為了避免長時間快取帶來的資訊失效,將失效時間定為了24h
3:非同步方法根據第一次資訊查詢的結果,第二次呼叫計算**介面,計算結果同樣存入快取,加上失效期
4:非同步執行完成之後,根據非同步id和執行結果,通知非同步服務執**況
5:前端直接在非同步伺服器中獲取執行結果,更加單純
優點:1:非同步流程和業務流程解耦,非同步流程進行了封裝,可以運用到類似需要首席執行官任務但是前端需要執行結果的場景
2:引入快取機制和失效機制,保證請求第三方介面資訊的及時性和有效性
缺點:1:服務之間的超時情況並沒有解決
2:非同步方法執行出現異常中斷,那麼前端還是會出現無限等待狀態
3:主業務開啟了非同步執行緒,但是非同步執行緒一直處於等待狀態,出現了多餘執行緒消耗情況
第二版遺留的問題
關於第乙個問題:服務之間呼叫的處理時間,我們經常會設定超時時間,無論是springcloud還是dubbo,都有這樣的配置,如果出現超時,開啟斷路器即可,雖然我們內部開發介面的時候,會要求介面的處理時間不能超過200ms,但是如果需要請求第三方介面,第三方介面的響應時間並不能控制,特別第三方介面的處理時間非常的長。
關於第二個問題:非同步方法屬於執行緒級,一般情況是不會出現突然中斷情況,但是一旦出現,那麼可以使用執行緒的interrupted方法來進行判斷
關於第三個問題:其實很多童鞋的設計中,這個問題不算問題,多餘的執行緒消耗也能接受,但是我們依然可以通過其他方案解決
解決方案:
1:引入mq,針對介面之間呼叫耗時非常長,超過斷路器耗時時,使用mq進行解耦,這樣就不存在超時和消耗多餘執行緒等待情況
2:針對非同步方法執行可能出現中斷,引入非同步服務步驟註冊和詢問機制,保證非同步流程一直處於執行中,或者可以冪等觸發。
那麼我們來看看第三版,最終版的設計,因為我們一直使用的阿里雲的rockermq,所以就不需要進行技術選型。
流程如下:
1:前端呼叫主業務服務介面,主業務方法根據需要開啟了非同步處理,首先在非同步服務中進行了非同步流程註冊,非同步服務返回乙個唯一的非同步執行id,介面直接返回了前端非同步id和執行狀態碼,告訴前端,現在已經開啟了非同步流程,需要查詢結果,請到非同步服務中
2:主業務服務介面開啟非同步方法,呼叫對外介面服務,該服務同步非同步流程執**況到非同步服務,然後進行第一次資訊查詢,,並且就查詢結果存入快取,為了避免長時間快取帶來的資訊失效,將失效時間定為了24h
3:對外介面服務將執行結果推送到mq中,mq在推送到主業務服務,主業務服務根據第一次資訊查詢結果呼叫第二次的**計算介面,同樣的套路再次執行
優點:1:引入mq之後,解決了問題一和問題三,關於介面處理超時和多餘執行緒消耗問題
2:增加同步非同步流程執行位置,用來解決問題二,關於非同步流程異常中斷,冪等重新發起的問題
缺點:1:主業務流程的方法將會被拆分成多個方法
原流程處理方法:
public
void
main()
新流程處理方法:
public
void
main()
@mqlisenter
("***xx"
)aresultprocess()
@mqlisenter
("***xx"
)bresultprocess()
2:增加了新的流程節點提高了介面不可用的風險
3:增加了編碼難度
非同步服務使用的場景並不是那麼廣泛,一般的場景幾乎使用不到它,除非出現一些條件比較苛刻的情況,作者所在的公司,主要使用非同步服務都是提供給後端運營使用
1:比如需要大批量製卡,但是需要知道製卡結果
2:比如需要匯出大量資料,比如幾百萬條記錄
3:比如需要大批量匯入,並且需要知道處理結果
3:比如上面的坑爹場景
產品投產之後,大boss發現使用者體驗實在太差,在加上市場反饋不好,這個專案涼涼了,再一次遭受到了社會的毒打┭┮﹏┭┮,所以奉勸小夥伴們一句,如果是探索性專案,還是先解決有無問題吧,過猶不及就是這個道理!
基於事件的非同步模式。
由於乙個類可以不用顯示的啟動或者管理執行緒而有多執行緒的能力,因此通過這就提供了乙個簡單的手段來實現,基於事件的非同步模式 event based asynchronous pattern eap 它同時也具有以下特徵 可協調的退出模式。當工作執行緒完成時,可以安全的更新wpf或者windowfor...
基於事件的非同步程式設計
基於事件的非同步模式具有多執行緒應用程式的優點,同時隱藏了多執行緒設計中固有的許多複雜問題。使用支援此模式的類,你將能夠 同時執行多個操作,每個操作完成時都會接到通知。等待資源變得可用,但不會停止 阻止 你的應用程式。使用熟悉的事件和委託模型與掛起的非同步操作通訊。支援基於事件的非同步模式的類將具有...
基於wcf的非同步上傳
operationcontract public void doupload string filename,byte context,bool 上傳目錄 string folder upload if system.io.directory.exists folder 檔案讀寫模式 filemod...