API 設計中性能提升的 10 個建議

【引子】前些的時候, 一好友約我聊一聊 API 的設計。當時覺得彷彿有萬語千言,但我又難以脫口而出 1、2、3。原來,即便是工作的日常,也缺乏一個系統性的思考和整理。API 的設計涉及到的方面很多, 分類是一個基本的思考方式。如果可以形成一個系列性的文字,那就從性能開始吧。

就像任何性能一樣,API 性能主要取決於如何響應不同類型的請求。例如: 典型的電商場景,顯示用戶當前的訂單。應用程序從一個 API 獲取訂單詳情。但是,如果希望用戶在一個地方能查看他們所有的訂單,這意味着,我們的 API 現在將返回比以前更多的數據,後臺的負載會更大。

如何確保 API 能夠將所有數據返回給用戶,而不會出現延遲、服務器錯誤和過多請求等問題呢?

一般地, 如何在 API 設計中提升性能還沒有梳理出完整的方法論,但就 REST API 而言,根據多年的經驗和教訓,這裏總結了 10 點建議。

1 啓用日誌,建立監控

API 的監控是最重要的,沒有之一。

擁有日誌、監控和告警可以幫助我們在潛在問題變成真正問題之前診斷並糾正問題。如果沒有啓用日誌記錄,並且存在潛在問題,那麼我們將無法跟蹤性能指標,或者在特定請求中定位問題發生的位置。奢侈一點的話, 要嘗試全鏈路跟蹤系統,儘管成本較高,但物有所值。

2 提升網速,帶寬足夠

即便 API 設計的性能非常強大,也扛不住緩慢的網絡延遲。不可靠的網絡可能會導致宕機,導致違反 SLA、服務條款以及曾經向客戶做出的承諾。必須要投資適當的網絡基礎設施,以便我們能夠維持所需的性能水平,有時候可以通過利用和購買足夠的雲資源來實現。

3 減少有效負載

如果響應數據的有效負載非常大,將會減慢請求完成的時間,並且影響性能。簡單來說,可以使用 GZip 壓縮來減少有效負載的大小,在 Web API 上使用 Deflate 壓縮,或者可以將 Accept-EncodingRequest 更新爲 Gzip。有效的數據壓縮能夠減少在 Web 應用程序上響應的下載量,同時提高上傳速度。

4 使用緩存

緩存是提高 API 性能的最簡單的方法之一。

如果有經常返回相同響應的請求,那麼該響應的緩存將有助於避免額外的服務調用和數據庫查詢。需要注意的是,應確保在緩存使用的生命週期,尤其是在發生數據更新的時候進行。此外,緩存增強了可伸縮性,服務端可以通過設置響應頭來提高緩存能力,比如 Cache-Control、 Expires、 Pragma、 Last-Modified 等等。

5 流控與頻控

API 遭受 DDoS 攻擊是惡意的,但有時候也可能是工程師無意造成的。例如工程師在某個本地應用程序的循環中執行調用 API 的調用。一般地,可以通過監視每個 IP 地址或每個 SSO 令牌發生的事務數量來避免這種情況。此外,頻控和流控也是實現安全性的重要手段,兩者都是爲了性能而實現限速的方式,有助於處理 API 的意外調用並主動監視和識別可能的惡意活動。

6 嘗試 HTTP 的標準方法

嘗試使用 HTTP 的標準方法,對 API 的性能會有一定的幫助。

dFb4mZ

例如,PUT 和 PATCH 操作在更新資源方面是相似的,但執行更新的方式是不同的。PUT 操作通過向整個資源發送更新來更新資源。PATCH 操作只對需要更新的資源應用部分更新,由此產生的 PATCH 調用可以產生更小的有效負載,從而提高性能。需要注意的是 PATCH 調用可不是冪等的。

7 嘗試標準的 HTTP 狀態碼

我們可以進一步對響應進行標準化、細分和限制,這有助於降低結果的複雜性,並通過僅針對客戶所要求的內容提供響應結果來改善整個客戶體驗。嘗試使用標準的 HTTP 狀態碼是一種不錯的方式。顯然,響應的狀態由其狀態代碼指定: 1xx 表示信息,2xx 表示成功,3xx 表示重定向,4xx 表示客戶機錯誤,5xx 表示服務器錯誤。例如,使用 HTTP 狀態碼,並且只使用響應體提供錯誤細節。

HTTP/1.2 400 Bad Request
Content-Type: application/json
{
    "error": "Expected xxx in xxx"
}

8 動靜分離,使用 CDN

如果有大量的後臺進程,可以在單獨的線程上運行這些進程,以避免阻塞請求。常見的一種方式是將 API 請求中的靜態資源分離開,可以使用內容交付網絡(CDN)來更快地服務不同地區請求中的靜態資源。

9 啓用分頁,過濾排序

對於大型數據集,限制返回的數據量是至關重要的。此外,可能希望指定要包含在響應中的資源的字段或屬性,從而限制返回的數據量,最終希望查詢特定的值並對返回的數據進行排序。

分頁有助於從多個響應創建大量的內容。這種優化有助於改進響應,同時保存、傳輸、顯示給客戶的數據。當鏈接在響應中返回時,API 變得更具自我描述性。對於在支持分頁的響應中返回的集合,“first”、“ last”、“ next”和 “ prev” 鏈接多少都是有益的。

10 使用性能更優的應用框架

應用框架的使用是爲了提高開發效率,如果爲了性能進行適當的優化和增強,也可以爲業務和客戶提供極其強大的體驗。一些框架專門用於構建 REST API,可以幫助我們在不犧牲生產力的前提下提升性能。例如,在 python 中,Web 應用框架衆多,像 Django 、Flask、Tornado、Falcon 等,就性能而言,Falcon 和 Tornado 可能是不錯的選擇,在 Node 中,Restify 似乎也不錯的選擇,但是我還沒有在生產環境來測試它。總的來說,基於 Go 語言的應用框架是非常值得關注的。

總之,業務需求和客戶期望總是隨着時間而變化的,我們有責任決定如何以高效的方式構建高性能的 API,從而幫助我們實現並超越目標。通過根據特定的 API 和用例來確定 API 與什麼服務交互,以及調用的頻率,從哪裏調用等等,我們可以用不同的方式實現高性能的 API。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/NQSgECerdR2rM06ugp4qjQ