上周有個朋友問我說:
沈老師,我們有很多服務依賴第三方接口,他們的接口不穩定,從而影響我們的服務,有沒有什么方法避免?
今天和大家聊一聊這個問題。
首先,可以將第三方接口,收口到一個服務內。
這樣,可以避免每個調用方都依賴于第三方服務:
(1)解除調用方與第三方接口的耦合;
(2)當第三方的接口變動時,只有服務需要修改,而不是所有調用方均修改;
此時,接口調用流程是什么樣的呢?

如上圖1-4所述:
(1)業務調用方調用內部service;
(2)內部service跨公網調用第三方接口;
(3)第三方接口返回結果給內部service;
(4)內部service返回結果給業務調用方;
封裝了服務之后,還存在什么潛在的問題呢?

內部服務可能對上游業務提供了很多服務接口,當有一個接口跨公網第三方調用超時時,可能導致所有接口都不可用,即使大部分接口不依賴于跨公網第三方調用。
為什么會出現“一個第三方接口超時,所有接口都不可用”的情況呢?
內部服務對業務方提供的N個接口,會共用服務容器內的工作線程(假設有100個工作線程)。
假設這N個接口的某個接口跨公網依賴于第三方的接口,發生了網絡抖動,或者接口超時(不妨設超時時間為5秒)。
潛臺詞是,這個工作線程會被占用5秒鐘,然后超時返回業務調用方。
假設這個請求的吞吐量為20qps,言下之意,很短的時間內,所有的100個工作線程都會被卡在這個第三方超時等待上,而其他N-1個原本沒有問題的接口,也得不到工作線程處理。
如何來進行優化呢?
常見的方案有三種:
(1)增大工作線程數(不根本解決問題);
(2)降低超時時間(不根本解決問題);
(3)垂直拆分,N個接口拆分成若干個服務,使得在出問題時,被牽連的接口盡可能少(依舊不根本解決問題,難道一個服務只提供一個接口嗎?);
還能如何優化呢?
異步代理法,是一種很常見的架構實踐。
業務場景:通過OpenID實時獲取微信用戶基本信息。
解決方案:增加一個代理,向服務屏蔽究竟是“本地實時”還是“異步遠程”去獲取返回結果。

本地實時流程如上圖1-5:
(1)業務調用方調用內部service;
(2)內部service調用異步代理service;
(3)異步代理service通過OpenID在本地拿取數據;
(4)異步代理service將數據返回內部service;
(5)內部service返回結果給業務調用方;
遠程異步流程如上圖6-8粗箭頭的部分:
(6)異步代理service定期跨公網調用微信服務;
(7)微信服務返回數據;
(8)刷新本地數據;
這種方案有什么優缺點呢?
優點:公網抖動,第三方接口超時,不影響內部接口調用。
缺點:本地返回的不是最新數據(很多業務可以接受數據延時)。
畫外音:有時候,內部service和異步代理service可以合成一個service。
還有其他的方法嗎?
第三方接口備份與切換,也是一種常見的實踐。
業務場景:調用第三方短信網關,或者電子合同等。
解決方案:同時使用(或者備份)多個第三方服務。

流程如上圖1-4:
(1)業務調用方調用內部service;
(2)內部service調用第一個三方接口;
(3)超時后,調用第二個備份服務,未來都直接調用備份服務,直到超時的服務恢復;
(4)內部service返回結果給業務調用方;
這種方案有什么優缺點呢?
優點:公網抖動,第三方接口超時,不影響內部接口調用(初期少數幾個請求會超時)。
缺點:不是所有公網調用都能夠像短息網關,電子合同服務一樣有備份接口的,像微信、支付寶等就只此一家。
還有其他的方法嗎?
異步調用法,也是一種實踐。
業務場景:本地結果,同步第三方服務,例如用戶在58到家平臺下單,58到家平臺需要通知平臺商家為用戶提供服務。
解決方案:本地調用成功就返回成功,異步調用第三方接口同步數據(和異步代理有微小差別)。

本地流程如上圖1-3:
(1)業務調用方調用內部service;
(2)內部service寫本地數據;
(3)內部service返回結果給業務調用方成功;
異步流程如上圖4-5粗箭頭的部分:
(4)異步service定期將本地數據取出(或者通知也行,實時性好);
(5)異步調用第三方接口同步數據;
這種方案有什么優缺點呢?
優點:公網抖動,第三方接口超時,不影響內部接口調用。
缺點:不是所有業務場景都可以異步同步數據。
總結
跨公網調用第三方,可能存在的問題:
(1)公網抖動,第三方服務不穩定,影響自身服務;
(2)一個接口超時,占住工作線程,影響其他接口;
降低影響的優化方案有:
(1)增大工作線程數;
(2)降低超時時間;
(3)服務垂直拆分;
任何脫離業務的架構方案都是耍流氓,可以結合業務實施方案:
(1)業務能接受舊數據:讀取本地數據,異步代理定期更新數據;
(2)有多個第三方服務提供商:多個第三方互備;
(3)向第三方同步數據:本地寫成功就算成功,異步向第三方同步數據;
希望第三方的服務掛掉,不再影響大家的服務。