我呼叫第三方介面遇到的13大坑
來源:蘇三說技術
前言
在實際工作中,我們經常需要在專案中呼叫第三方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如何保證資料一致性?終止當前程式,該如何處理後續的流程?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024924/viewspace-2946120/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 進擊的Bug 那些年我遇到的大坑
- 進擊的Bug 那些年我遇到的大坑2
- 進擊的Bug---那些年我遇到的大坑3
- 使用Go呼叫第三方介面Go
- 我擦 遇到個大坑啊 C和C++混合編譯問題C++編譯
- 用WebService呼叫第三方天氣介面Web
- ABAP 呼叫第三方 API,遇到亂碼該怎麼辦?API
- 當Synchronized遇到這玩意兒,有個大坑,要注意!synchronized
- itchat—python實現呼叫微信介面的第三方模組Python
- 執行緒池遇到父子任務,有大坑,要注意!執行緒
- 記錄一個這幾天大家安裝 laradock 遇到的大坑!!!
- PHP CURL 業務呼叫第三方介面設定超時時間PHP
- 前端的初步----呼叫介面前端
- Qt入門(13)——Qt的呼叫退出QT
- 字串拼接這個隱藏大坑,我表示不服~字串
- app 呼叫介面APP
- webservice介面呼叫Web
- 我面試遇到的智力題面試
- MediaSessionCompat::setMetadata呼叫時遇到的深坑Session
- 快手二面:你有沒有呼叫過第三方介面?碰到過哪些坑?
- FlutterUI 呼叫系統渲染引擎-13FlutterUI
- 呼叫後端介面 / 介面適配後端
- 如何呼叫api介面API
- 呼叫後端介面後端
- 呼叫微信介面token的問題
- 開發環境部署之 Homestead 大坑,我是這樣爬出來的開發環境
- 我遇到的有趣面試題:破解程式面試題
- 我靠!Semaphore裡面居然有這麼一個大坑!
- Http介面呼叫示例教程HTTP
- 實現呼叫API介面API
- C++呼叫C介面C++
- 併發序列呼叫介面
- 微信紅包介面呼叫(rails)AI
- 前端如何取消介面呼叫前端
- 介面呼叫超時的實現原理
- [求助]..新手!遇到struts呼叫sessionbean問題?SessionBean
- Go GC 機制的大坑GoGC
- 介面回撥的原理:介面變數 呼叫 被類實現的介面的方法變數