接口設計的16個原則

接口設計須要考慮哪些方面

    1. 接口的命名。前端

    2. 請求參數。mysql

    3. 支持的協議。nginx

    4. TPS、併發數、響應時長。程序員

    5. 數據存儲。DB選型、緩存選型。web

    6. 是否須要依賴於第三方。redis

    7. 接口是否拆分。sql

    8. 接口是否須要冪等。數據庫

    9. 防刷。json

    10. 接口限流、降級。後端

    11. 負載均衡器支持。

    12. 如何部署。

    13. 是否須要服務治理。

    14. 是否存在單點。

    15. 接口是否資源包、預加載仍是內置。

    16. 是否須要本地緩存。

    17. 是否須要分佈式緩存、緩存穿透怎麼辦。

    18. 是否須要白名單。

當咱們設計接口,咱們或多或少都會有上面列舉的一些考慮,咱們只有想的更多才能讓讓咱們的接口更加完善,我我的以爲100%完美的接口是不存在,只有適合纔是最重要。

接口設計原則

原則一:必須符合Restful,統一返回格式,約定業務層錯誤編碼,每一個編碼能夠攜帶可選的錯誤信息。

原則二: 命名必須規範、優雅。

原則三:單一性。

單一性是指接口要作的事情應該是一個比較單一的事情,好比登錄接口,登錄完成應該只是返回登錄成功之後一些用戶信息便可,但不少人爲了減小接口交互,返回一大堆額外的數據。

好比有人設計一個用戶列表接口,接口他返回每一條數據都是包含用戶了一大堆跟另外無關的數據,結果一問,原來其餘無關的數據是他下一步想要獲取的,想達成數據的懶加載。

原則四:可擴展。

接口擴展性,是指設計接口的時候多想一想多種狀況,多考慮各個方面,其實我以爲單獨將擴展性放在這裏也是不妥的,感受說的跟單一性有點相反的意思,其實這個不是這個意思。

這邊的擴展性是指咱們的接口充分考慮客戶端,想一想他們是如何調用的,他要怎樣使用個人代碼,他會如何擴展個人代碼,不要把過多的工做寫在你的接口裏面,而應該把更多的主動權交給客戶程序員。

如獲取不一樣的列表數據接口,咱們不可能將每一個列表都寫成一個接口。 還有一點,我這裏特別想指出來的是不少開發人員爲了省事(姑且只能這麼理解),將接口設計當成只是 app 頁面展現。

這些人將一個頁面展現就用一個接口實現,而不考慮這些數據是否是屬於不一樣的模塊、是否是屬於不一樣的展現範疇、結果下次視覺一改,整個接口又得重寫,不能複用。

原則五:必須有文檔。

良好的接口設計,離不開清晰的接口文檔表述。文檔表述必定要足夠詳細

原則六:產品心。

爲何我說要有產品心?由於我以爲不少人忽略了這一點。我來講一下假如開發一個app,若是一開始連個交互文檔給你都沒有的話,你怎麼設計接口?

因此我以爲做爲一個服務端後臺開發人員應該要有產品心,特別是對於交互文檔應該好好理解,由於這些都會對咱們的接口設計有很大的影響。

我在設計接口的時候就很常發現不少交互文檔根本就走不通,產品沒有考慮到位,交互文檔缺失,這時候做爲一個開發要主動推進,完善。

原則七:第三方服務接口數據能緩存就緩存。

原則八:第三方服務須要作降級。

原則九:建議消除單點。

原則十:接口粒度要小。

原則十一:客戶端能處理的邏輯就不要給服務端處理,減小服務端壓力。

原則十二:資源預加載。

原則十三:不要過分設計。

原則十四:緩存儘可能不要穿透。

原則十五:接口能緩存就緩存。

原則十六:思辨大於執行

如何保證接口的高可用、高性能

上面也列舉不少須要考慮和設計的原則,其實還有不少方面,我這邊也不是特別全面。

居於上面列舉的這些考慮點,其實這邊說服務是更恰當,能把上面說的點作好,其實接口也是比較可靠,如何設計以及保證接口的高可用和高性能。能夠思考一下如下幾個 point

高性能:若是咱們發現這個接口tps和響應時間沒有達到咱們的要求怎麼辦。

    • A:數據存儲方面:咱們會想數據庫有沒有分庫、分表、有沒有作主從,有沒有讀寫分離、字段是否有加索引、是否存在慢 sql,數據庫引擎是否選用合適、是否是用了事務;

      其次咱們會想到是否是引用了分佈式緩存、緩存 key 大小是否合適,失效時間是否設置合理,會不會大量緩存穿透、有沒有引入本地緩存。

    • B:業務方面:是否有大量的計算、可否異步處理。是否須要引入線程池或者 MQ 來異步處理任務。有沒有必要將接口進行垂直拆分和水平拆分、將接口粒度變小。

    • C:其餘方面:nginx 層面作緩存、加機器、用 ssd,資源放 cdn,多機房部署、資源文件預加載。

高可用:如何保證服務高可用,須要從幾個維度來實現:

    • A:消除單點,基於高可用第二位。

    • B:能作集羣的所有作集羣。譬如 Redis 集羣、mysql集羣、MongoDB副本集。

    • C:能作讀寫分離的都作讀寫分離。

    • D:異地多機房部署,接入 GSLB

    • E:必須有限流、降級機制。

    • F:監控。高可用的保證,基於第一位。

下圖是從一個基本的請求出發來梳理須要涉及到各個段,以及各個端能作的事情。談談接口服務,但不侷限於接口自己。

    1. 客戶端:資源預加載、限制請求、數據上報。我這邊就拿客戶端來舉個例子。接口服務所依賴的資源包或者一些公共配置預加載在本地,減小接口的交互,經過請求配置文件是否更新,code是不是304等來;

      接口作一些請求限制,好比搶紅包、搶券等,單位時間內N次點擊只請求一次等;接口失敗數據上報來;這就是客戶端能夠作到的對接口有幫助的事情

    2. GSLB/HttpDNS:多機房部署、流量切換、域名劫持,通常技術和業務比較成熟的公司這一層。

    3. 資源文件放CDN。

    4. 負載均衡器:lVS+Nginx是互聯網經常使用的作負載均衡,能夠實現四層/七層負載均衡;這裏除了能夠分流、轉發之外,咱們用的更多的基於令牌桶限流、緩存。

    5. 本地緩存。本地緩存能減小咱們訪問DB或者分佈式緩存,本地緩存推薦使用guava,guava裏面有不少特性很好用,例如基於令牌桶的限流;當緩存失效時只穿透一個請求去訪問後端。

    6. 線程池。

    7. 模塊拆分。將一個項目按功能模塊拆分,一個接口也能夠按業務粒度進行拆分。

    8. 數據中心。提供數據支撐,譬如黑名單。

    9. 數據庫。加索引、分庫、分表、讀寫分離

    10. 分佈式緩存。數據分片、拆分大key,並作集羣,採用分佈式鎖

    11. MQ。作接口拆分利器,異步操做。

    12. 其餘服務。限流、防刷以及降級(特別是第三方服務,保證第三方服務down掉不要影響咱們自身的服務)。在這裏也須要考慮作第三方數據的緩存或者持久化,譬如實名認證、身份證認證等。

    13. 監控。監控永遠是必須的,能讓你第一時間知道接口服務是否ok

我的小分享

1)接口Restful,統一返回格式,約定業務層錯誤編碼,每一個編碼能夠攜帶可選的錯誤信息

在前司,客戶端和服務之間是有統一的數據返回格式,約定各層的編碼,能夠經過編碼位數以及編碼就能夠看出是那一層出問題。

我以爲這對咱們定位問題以及維護來講具備莫大的意義,並對異常也進行捕捉,封裝成對應的 code,我以前閱讀一些人的代碼發現其項目根本沒有作這一層,由於簡單而不作我以爲有失所望。

2)採用 hybird 模式

採用 hybird 模式涉及到資源預加載的問題,在不少項目裏面都大量使用,譬如前司的生活服務,就採用了 hybird 模式,先將資源文件(包含圖片、前端頁面)打包放到服務器並經過版本號進行管理,並經過一個總的配置文件來管理,若是是H5頁面能夠進行模板預先設計,down到本地。

配置文件格式:

  *文件1*        name:xxx        url:http:xxxx        md5:xxxx   *文件2*        name:zzz        url:http:zzzz        md5:zzz

客戶端每次啓動應用或者定時請求總的配置文件,經過http code是不是304判斷是否須要下載這個總的配置文件,若是code是200,那麼下載這個配置,比較那個文件發生變化,並將其下載。這樣的好處:

    1. 減小接口的交互;

    2. 資源預加載,節省流量,打開頁面更加流暢,對於服務端來講字須要返回數據json串就行,而不須要其餘,減小服務端壓力;

    3. 方便開發人員,資源管理更加簡潔,好比作活動須要的h5頁面,只須要前端上傳對應的h5資源包到服務端,不須要經過後端開發人員就能夠搞定。

雖然這個原理很簡單,可是如今不少app仍是沒有作這個,都是經過填寫一個url,加載網頁的方式去打開,體驗性太不友好。

3)客戶端

客戶端跟服務端就是接口請求的關係,不少時候須要要求客戶端作一些數據緩存的工做以及一些檢驗工做。在前司已經好幾回給客戶端的同窗坑過了,客戶端同窗接口亂調用,死循環調用。

一次是作一個關於事件提醒的功能,須要天天定時調用調用服務端一個接口,結果客戶端的同窗寫了一個 bug 致使請求每隔一兩秒就調用一次,致使服務器這邊此接口 pv 翻了N倍,並且這個 bug 經過測試同窗很難測試出來;

還有一次發現服務端一段時間之後 UV 不見漲,可是PV卻漲的很猛,定位發現是客戶端同窗A圖省事在一個方法裏面調用了N個接口,也就是模板方法。

由於版本更新,同窗B須要作一個新的功能,而後也調用了A同窗的接口致使,從而致使PV上升,其實B同窗徹底不須要調用這麼多接口。這些都是真實案例,因此這裏須要有一個監控接口異常的機制。

4)思辨大於執行

寫到這裏以爲這個很是重要,思辨大於執行,意味着咱們不是一股腦就去幹,也不是不去幹,咱們作事情須要思考、辨別;從而讓事情更高效、更好、更有力的執行。接口設計也同樣,須要咱們去思辨。

5)本地緩存、分佈式緩存以及異步

緩存在前司主要分爲客戶端緩存、CDN緩存、本地緩存(guava)、Redis緩存。

在MZ早期是接口是採用 DB+本地緩存的方式提供數據,但這種模式DB壓力大,接口吞吐量小,本地緩存多機難一致性、更新不及時問題。

爲了解決這些問題,引入分佈式緩存,並經過 Task 將業務數據刷到 Redis,接口只訪問 redis,不會訪問 DB,及時 DB 故障也不會影響功能。

不一樣的業務系統系統經過 MQ 來解耦,多機房不是經過 MQ 來實現數據的一直。

好比,評論,先經過寫 Redis,寫 MQ 來實現數據在多機房同步,再經過 task 將 Redis 中評論同步到 DB 中。

接口設計涉及方方面面,這邊也只談到一個大概,雖然有點泛泛而談,但願此拙文對你有所啓示。

6)數據庫

數據庫分庫分表,通常都是經過 userId 或者 imei 或者 mac 地址來分表,單表數據量控制在500w之內,這須要咱們提早估算好數據量,儘可能避免數據的遷移。

在前司,數據庫通常都是採用 mysql+MongoDB 兩種,MySQL存儲用戶的用戶數據,MongoDB 存儲業務數據,就像閱讀和生活服務裏面的業務數據就存儲在 MongoDB 裏面。

在數據庫這層,咱們主要也是經過主從模式、讀寫分離、分庫、分表來實現數據的可用性。

7)業務

業務儘量拆分、獨立部署、將項目按業務劃分、按功能劃分等。譬如生活服務,咱們當時主要拆分紅管理後臺 admin、任務 task、活動、web、數據展現模塊。

8)數據中心

每一個大一點的公司都有數據部門,咱們這邊能夠經過數據中心的數據分析來達到咱們須要的數據。

好比黑名單,推廣效果、活動數據。咱們能夠經過這些完善咱們的接口功能。以前在前司作了個數據處理後異步加載到 Redis 來實現數據利用的項目。

相關文章
相關標籤/搜索