
前言
在實際作業中,我們經常需要在專案中呼叫第三方API介面,獲取資料,或者上報資料,進行資料交換和通信,
那么,呼叫第三方API介面會遇到哪些問題?如何解決這些問題呢?
這篇文章就跟大家一起聊聊第三方API介面的話題,希望對你會有所幫助,

1 域名訪問不到
一般我們在第一次對接第三方平臺的API介面時,可能會先通過瀏覽器或者postman呼叫一下,該介面是否可以訪問,
有些人可能覺得多次一舉,
其實不然,
有可能你呼叫第三方平臺的API介面時,他們的介面真的掛了,他們還不知道,
還有一種最重要的情況,就是你的作業網路,是否可以訪問這個外網的介面,
有些公司為了安全考慮,對內網的開發環境,是設定了防火墻的,或者有一些其他的限制,有些ip白名單,只能訪問一些指定的外網介面,
如果你發現你訪問的域名,在開發環境訪問不通,就要到運維同學給你添加ip白名單了,
2 簽名錯誤
很多第三方API介面為了防止別人篡改資料,通常會增加數字簽名(sign)的驗證,
sign = md5(多個引數拼接 + 密鑰)
在剛開始對接第三方平臺介面時,會遇到引數錯誤,簽名錯誤等問題,
其中引數錯誤比較好解決,重點是簽名錯誤這個問題,
簽名是由一些演算法生成的,
比如:將引數名和引數值用冒號拼接,如果有多個引數,則按首字母排序,然后再將多個引數一起拼接,然后加鹽(即:密鑰),再通過md5,生成一個簽名,
如果有多個引數,你是按首字母倒序的,則最后生成的簽名會出問題,
如果你開發環境的密鑰,用的生產環境的,也可能會導致生產的簽名出現問題,
如果第三方平臺要求最后3次md5生成簽名,而你只用了1次,也可能會導致生產的簽名出現問題,
因此,介面簽名在介面聯調時是比較麻煩的事情,
如果第三方平臺有提供sdk生成簽名是最好的,如果沒有,就只能根據他們檔案手寫簽名演算法了,
3 簽名過期
通過上面一步,我們將簽名調通了,可以正常訪問第三方平臺獲取資料了,
但你可能會發現,同一個請求,15分鐘之后,再獲取資料,卻回傳失敗了,
第三方平臺在設計介面時,在簽名中增加了時間戳校驗,同一個請求在15分鐘之內,允許回傳資料,如果超過了15分鐘,則直接回傳失敗,
這種設計是為了安全考慮,
防止有人利用工具進行暴力破解,不停偽造簽名,不停呼叫介面校驗,如果一直窮舉下去的話,總有一天可以校驗通過的,
sign = md5(多個引數拼接 + 密鑰 + 時間戳)
因此,有必要增加時間戳的校驗,
如果出現這種情況,不要慌,重新發起一次新的請求即可,
4 介面突然沒回傳資料
如果你呼叫第三方平臺的某個API介面查詢資料,剛開始一直都有資料回傳,
但突然某一天沒回傳資料了,
但是該API介面能夠正常回應,
不要感到意外,有可能是第三方平臺將資料洗掉了,
我對接完第三方平臺的API介面后,部署到了測驗環境,發現他們介面竟然沒有回傳資料,原因是他們有一天將測驗環境的資料刪完了,
因此,在部署測驗環境之前,要先跟對方溝通,要用哪些資料測驗,不能洗掉,
5 token失效
有些平臺的API介面在請求之前,先要呼叫另外一個API介面獲取token,然后再header中攜帶該token資訊才能訪問其他的業務API介面,
在獲取token的API介面中,我們需要傳入賬號、密碼和密鑰等資訊,每個介面對接方,這些資訊都不一樣,
我們在請求其他的API介面之前,每次都實時呼叫一次獲取token的介面獲取token?還是請求一次token,將其快取到redis中,后面直接從redis獲取資料呢?
很顯然我們更傾向于后者,因為如果每次請求其他的API介面之前,都實時呼叫一次獲取token的介面獲取token,這樣每次都會請求兩次介面,性能上會有一些影響,
如果將請求的token,保存到redis,又會出現另外一個問題:token失效的問題,
我們呼叫第三方平臺獲取token的介面獲取到的token,一般都有個有效期,比如:1天,1個月等,
在有效期內,該API介面能夠正常訪問,如果超過了token的有效期,則該API介面不允許訪問,
好辦,我們把redis的失效時間設定成跟token的有效期一樣不就OK了?
想法是不錯,但是有問題,
你咋保證,你們系統的服務器時間,跟第三方平臺的服務器時間一模一樣?
我之前遇到過某大廠,提供了獲取token介面,在30天內發起請求,每次都回傳相同的token值,如果超過了30天,則回傳一個新的,
有可能出現這種情況,你們系統的服務器時間要快一些,第三方平臺的時間要慢一些,結果到了30天,你們系統呼叫第三方平臺的獲取token介面獲取到了token還是老的token,更新到redis中了,
過一段時間,token失效了,你們系統還是用老的token訪問第三方平臺的其他API介面,一直都回傳失敗,但獲取新的token卻要等30天,這個時間太漫長了,
為了解決這個問題,需要捕獲token失效的例外,如果在呼叫其他的API介面是發現token失效了,馬上請求一次獲取token介面,將新的token立刻更新到redis中,
這樣基本可以解決token失效問題,也能盡可能保證訪問其他介面的穩定性和性能,
6 介面超時
系統上線之后,呼叫第三方API介面,最容易出現的問題,應該是介面超時問題了,
系統到外部系統之間,有一條很復雜的鏈路,中間有很多環節出現問題,都可能影響API介面的相應時間,
作為API介面的呼叫方,面對第三方API介面超時問題,除了給他們反饋問題,優化介面性能之外,我們更有效的方式,可能是增加介面呼叫的失敗重試機制,
例如:
int retryCount=0;
do {
try {
doPost();
break;
} catch(Exception e) {
log.warn("介面呼叫失敗")
retryCount++;
}
} where (retryCount <= 3)
如果介面呼叫失敗,則程式會立刻自動重試3次,
如果重試之后成功了,則該API介面呼叫成功,
如果重試3次之后還是失敗,則該API介面呼叫失敗,
7 介面回傳500
呼叫第三方API介面,偶爾因為引數的不同,可能會出現500的問題,
比如:有些API介面對于引數校驗不到位,少部分必填欄位,沒有校驗不能為空,
剛好系統的有些請求,通過某個引數去呼叫該API介面時,沒有傳入那個引數,對方可能會出現NPE問題,而該介面的回傳code,很可能是500,
還有一種情況,就是該API介面的內部bug,傳入不同的引數,走了不同的條件分支邏輯,在走某個分支時,介面邏輯出現例外,可能會導致介面回傳500,
這種情況做介面重試也沒用,只能聯系第三方API介面提供者,反饋相關問題,讓他們排查具體原因,
他們可能會通過修復bug,或者修復資料,來解決這個問題,
8 介面回傳404
如果你在系統日志中發現呼叫的第三方API介面回傳了404,這就非常坑了,
如果第三方的API介面沒有上線,很可能是他們把介面名改了,沒有及時通知你,
這種情況,可以錘他們了,
還有一種情況是,如果第三方的API介面已經上線了,剛開始介面是能正常呼叫的,
第三方也沒有改過介面地址,
后來,突然有一天發現呼叫第三方的API介面還是出現了404問題,
這種情況很可能是他們網關出問題了,最新的配置沒有生效,或者改了網關配置導致的問題,
總之一個字:坑,
9 介面回傳少資料了
之前我調過一個第三方的API介面分頁查詢資料,接入非常順利,但后來上線之后,發現他們的介面少資料了,
一查原因發現是該分頁查詢介面,回傳的總頁數不對,比實際情況少了,
有些小伙伴可能會好奇,這么詭異的問題我是怎么發現?
之前呼叫第三方API介面分頁查詢分類資料,保存到我們的第三方分類表中,
突然有一天,產品反饋說,第三方有個分類在分類樹中找不到,
我確認之后,發現竟然是真的沒有,
從呼叫第三方API介面的回應日志中,也沒有查到該分類的資料,
這個API介面是分頁查詢介面,目前已經分了十幾頁查詢資料,但還是沒有查到我們想要的分類,
之前的做法是先呼叫一次API介面查詢第一頁的資料,同時查出總頁數,然后再根據總頁數回圈呼叫,查詢其他頁的資料,
我當時猜測,可能是他們介面回傳的總頁數有問題,
于是,可以將介面呼叫邏輯改成這樣的:
-
從第一頁開始,后面每呼叫一次API介面查資料,頁數就加1,然后判斷介面回傳的資料是否小于pageSize, -
如果不小于,則進行下一次呼叫, -
如果小于,則說明已經是最后一頁了,可以停止后續呼叫了,
驗證之后發現這樣果然可以獲取那個分類的資料,只能說明第三方的分頁查詢介面回傳的總頁數比實際情況小了,
10 偷偷改引數了
我之前呼叫過某平臺的API介面獲取指標的狀態,之前根據雙方約定的狀態有:正常和禁用 兩種,
然后將狀態更新到我們的指標表中,
后來,雙方系統上線運行了好幾個月,
突然有一天,用戶反饋說某一條資料明明洗掉了,為什么在頁面上還是可以查到,
此時,我查我們這邊的指標表,發現狀態是正常的,
然后查看呼叫該平臺的API介面日志,發現回傳的該指標的狀態是:下架,
what?
這是什么狀態?
跟該平臺的開發人員溝通后,發現他們改了狀態的列舉,增加了:上架、下架等多個值,而且沒有通知我們,
這就坑了,
我們這邊的代碼中判斷,如果狀態非禁用狀態,都認為是正常狀態,
而下架狀態,自動被判斷為正常狀態,
經過跟對方溝通后,他們確認下架狀態,是非正常狀態,不應該顯示指標,他們改了資料,臨時解決了該指標的問題,
后來,他們按介面檔案又改回了之前的狀態列舉值,
11 介面時好時壞
不知道你在呼叫第三方介面時,有沒有遇到過介面時好時壞的情況,
5分鐘前,該介面還能正常回傳資料,
5分鐘后,該介面回傳503不可用,
又過了幾分鐘,該介面又能正常回傳資料了,
這種情況大概率是第三方平臺在重啟服務,在重啟的程序中,可能會出現服務暫時不可用的情況,
還有另外一種情況:第三方介面部署了多個服務節點,有一部分服務節點掛了,也會導致請求第三方介面時,回傳值時好時壞的情況,
此外還有一種情況:網關的配置沒有及時更新,沒有把已經下線的服務剔除掉,
這樣用戶請求經過網關時,網關轉發到了已經下線的服務,導致服務不可用,網關轉發請求到正常的服務,該服務能夠正常回傳,
如果遇到該問題,要盡快將問題反饋給第三方平臺,然后增加介面失敗重試機制,
12 檔案和介面邏輯不一致
之前還遇到一個第三方平臺提供的API查詢介面,介面檔案中明確寫明了有個dr欄位表示洗掉狀態,
有了這個欄位,我們在同步第三方平臺的分類資料時,就能夠知道有哪些資料是被洗掉的,后面可以及時調整我們這邊的資料,將相關的資料也做洗掉處理,
后來發現有些分類,他們那邊已經洗掉了,但是我們這邊卻沒洗掉,
這是啥情況呢?
代碼邏輯很簡單,我review了一下代碼,也沒有bug,為什么會出現這種情況呢?
追查日志之后發現,呼叫第三方平臺獲取分類介面時,對方并沒有把已洗掉的分類資料回傳給我們,
也就是說介面檔案中的那個dr欄位沒有什么用,介面檔案和介面邏輯不一致,
這個問題估計好多小伙伴都遇到過,
如果要解決這個問題,主要的方案有兩種:
-
第三方平臺按檔案修改介面邏輯,回傳洗掉狀態, -
我們系統在呼叫分類查詢介面之后,根據分類code判斷,如果資料庫中有些分類的code不在介面回傳值中,則洗掉這些分類,
13 欠費了
我們呼叫過百度的票據識別介面,可以自動識別發票資訊,獲取發票編號和金額等資訊,
之前是另外一個同事對接的介面,后來他離職了,
發票識別功能上線,使用了很長一段時間,一直都沒有出問題,
后來,某一天,生產環境用戶反饋發票識別不了了,
我查詢了相關服務的日志,沒有發現例外,這就奇怪了,
打開代碼仔細看了一下,發現那位同事的代碼中呼叫第三方的API介面,接收回應資料時,直接轉換成了物件,沒有列印當時回傳的字串,
莫非,介面回傳值有問題?
后來,我增加了日志,列印出了該介面真正的回傳內容值,
原因一下查到了,原來是欠費了,
如果出現該了例外,百度的API介面回傳的資料結構,用之前那位同事的物體有些引數沒法獲取到,
這是一個不小的坑,
我們在接收第三方API介面回傳資料時,盡可能先用字串接識訓傳值,然后將字串轉換成相應物體類,一定要將該回傳值在日志中列印出來,方便后面定位問題,
不要直接用物體物件接識訓傳值,有些API介面,如果出現不同的例外,回傳的資料結構差異比較大,
有些例外結果可能是他們網關系統直接回傳的,有些例外是他們業務系統回傳的,
其實,我們之前還遇到過其他坑,比如:呼叫分類樹查詢介面,但第三方回傳的資料有重復的id,我們這邊該如何處理這種例外資料呢?
我們在job中回圈呼叫第三方API介面獲取資料,如果其中某一次呼叫失敗了,是try/catch捕獲例外呢?繼續執行后面的呼叫,還是直接終止當前的程式?如果try/catch如何保證資料一致性?終止當前程式,該如何處理后續的流程?
作者|蘇三啊
本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/I-encountered-13-major-pitfalls-when-calling-third-party-interfaces.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/550658.html
標籤:其他
上一篇:年薪50W京東軟體測驗工程師的成長路 —— 我們都曾一樣迷茫
下一篇:返回列表
