程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> open api應用開發最佳實踐,api應用開發最佳實踐

open api應用開發最佳實踐,api應用開發最佳實踐

編輯:JAVA綜合教程

open api應用開發最佳實踐,api應用開發最佳實踐


        在公司的內部系統中,會存在一些接入第三方數據的場景,例如在攜程的app裡能看到藝龍的機票,在美團的酒店列表裡能找到去哪兒的酒店等。在自己的客戶端或者H5裡展示這些數據,一般會通過open-api對接的方式完成。最近正好在做一個open-api項目,場景是第三方可以通過調用open-api提供的http服務,在我方app裡面提供第三方的團購服務。本文主要總結一下系統設計時的一些實踐經驗。

系統設計

        系統包括2個應用,一個是web應用,一個是server應用,web應用對外提供http服務,service應用提供內部調用的api。為什麼不在一個應用裡面完成呢?這是為了保證項目的整潔干淨。web應用提供對外的api,不直接與數據庫打交道,而server為web項目提供rpc服務。系統設計的時序圖如下:

                                                圖1

        第三方調用web應用提供的restful api,按照我們提供的參數格式發起請求。open-api-web在對參數進行校驗之後,根據校驗結果返回錯誤信息or發起rpc調用。open-api-service為每個請求落地數據到數據庫,包括請求log、團單初始信息等。如果沒有異常,則會異步調用公司內部上單系統服務,同時返回一個初步的處理結果:團單初始化中or錯誤信息,由web應用返回給第三方。當異步調用結果出來之後,回調第三方提供的rest api,發送處理結果。

        為什麼要異步處理與內部上單系統的對接呢?這裡主要考慮到api的可用性和相應速度。在上單的過程中,涉及到圖片的上傳這樣的耗時操作,如果采用同步調用的方式,勢必會大大增加api的相應時間,影響api的可用性。

如何異步

        實現異步的方式有很多,總的來說,就是不要在同一個線程中把所有的事情完成。之前考慮了以下幾種方式:

        1. 封裝一個task,通過ExecutorService提交一個任務給線程池,由線程池分配一個線程,處理與上單系統對接的邏輯。

        2. 使用spring event,由於spring對Event的默認是同步的,可以對multicastEvent方法進行重寫,實現異步。

        3. 使用消息隊列,server端對團單做本地保存後,發送消息,同時server接收消息,處理消息。

        對這三種方式進行了分析,1和2比較接近,本質上都是另開線程處理,但是2比1更好,因為2實現了業務的解耦,發布event和處理event可以由不同的開發獨立完成。發布者只需要關心發布的邏輯,而接收者專注於與內部系統的對接。最後我們采用了第三種方式,因為第三種方式更穩定,原因在於消息隊列會對消息做持久化處理,當應用重啟或者宕機的時候,消息不會丟失,從而保證每一個消息都可以得到處理。

       對於消息的處理,要注意的是冪等處理。例如第三方創建團單,如果不進行冪等,可能會出現重復創建的問題。每次接受到創建請求時,先查詢數據庫中是否已保存相同團單的數據,如果已經存在則丟棄。而更新團單的時候,我們采用了版本號的方式。為每個已創建的團單分配一個版本號,初始值為0,當收到更新請求時,消息生產者先把版本號+1,再發送消息。消費者接受到消息後,與數據庫中版本號對比,只接受大於原始版本號的請求。如果滿足要求,則進行團單更新,更新成功後,把最新的版本號持久化到數據庫中。這樣就保證了,不重復處理請求,同時只處理最新的更新請求。

異常處理

        發生數據增刪改的api,需要將處理結果返回。對於請求執行過程中產生的業務邏輯錯誤或者運行時異常,如何處理呢?我們采用了定義ErrorCode和異常統一處理的方式。ErrorCode是一個枚舉類,定義了不同的業務異常,每個枚舉都包括了錯誤碼code和錯誤信息msg,例如 Parnert_NOT_FOUND(2001, “第三方不存在")。同時定義一個異常類BizException,當業務執行的過程中,發生與預期不符時,拋出該異常,同時把ErrorCode信息帶上。最後利用Spring AOP技術,定義一個切面,對所有執行的業務代碼進行代理,統一catch異常,對不同的異常進行包裝處理成Response,再將response返回。這樣做的好處是什麼呢?我認為主要有2點:1 異常code收攏到一個枚舉類,便於異常code統一定義和查詢 2 在切面對異常進行處理,避免異常處理代碼散落到各處,不利於維護。

        開發業務代碼時,只需要關心業務邏輯,出現與預期不符的情況時,拋出異常即可,至於怎麼處理無需關心。

安全控制

        open api需要對第三方做嚴格的校驗,避免惡意用戶隨意使用公司內部系統。為了保證其安全性,我們主要考慮3個方面:

        1. 錄入第三方基礎信息,落到本地數據庫,當第三方調用open api時,需要傳入第三方信息做校驗;

        2. http請求采用post方式;

        3. 簽名校驗。使用對稱加密MD5加密的方式,動態生成簽名。

問題排查

        第三方使用open api出現問題時,如何排查?首先,直接根據api返回的code和msg(由response對象封裝),就可以知道處理結果以及失敗原因。如果對於某次請求有異議,怎麼辦呢?我們希望可以還原現場,以便排查問題到底出在哪裡。所以我設計了一張log表,把每個請求的路徑和參數都記下來,這樣可以第三方id找到相應的原始請求數據。現場都還原了,到底是哪方的問題,也就清清楚楚了。同時,在本地的團單表中,對於處理失敗的單子,也記錄下失敗的原因,以做備查。

其他總總

       當然,還有很多值得思考的地方,例如流量控制、系統監控等,這些都是可以完善的地方。一個看似簡單的功能,想要做好,也是要多多思考才行

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved