← 主題

與 API 供應商的錢包轉帳:讓請求佇列保持暢通

平台與 API 供應商之間串接的轉帳呼叫如何塞爆請求佇列,以及佇列、快速回應和推送結果如何讓平台在供應商變慢時依然穩定。

平台保管使用者的錢包;API 供應商則運行平台所提供服務背後的伺服器。使用者要用某個供應商的服務前,資金從平台轉到供應商;用完之後再轉回來。大多數整合把這些轉帳做成雙向串接的同步 HTTP 呼叫。流量一大,這條鏈會同時塞滿雙方的請求佇列,一個變慢的供應商就能拖垮整個平台。你的平台穩不穩定,不該取決於別人的伺服器。

一筆轉帳就是一條請求鏈

使用者平台API 供應商開始使用服務平台的 worker 在等POST /transfer-in等供應商回應GET /wallet/verify供應商的 worker 也在等200 OK200或逾時,狀態不明GET /transfer/123每 2 秒一次,直到完成可以開始
改之前:一筆轉帳,靠一串 HTTP 呼叫完成

平台的 worker 在整趟往返中都被佔住,包括供應商回呼平台的那一段。供應商的 worker 則在等那次回呼時被佔住。雙方互相等待,所以流量上升時兩邊的連線池會同時塞滿。一次逾時就讓轉帳狀態不明,接著就是狀態輪詢和重試;如果沒有冪等鍵,重試還可能讓錢轉兩次。

一個慢供應商怎麼變成所有人的問題

活動開始轉帳變多
供應商 C 變慢150 ms → 5 秒
平台 worker 被佔住都在等 C
共用連線池用光所有請求排隊
請求逾時
重試與狀態輪詢請求更多
登入、儲值和其他供應商失敗都與 C 無關
一時變慢,演變成請求洪水

以下是推算範例,不是壓測結果(撰寫於 2026-11-09):每秒 500 筆轉帳,分散在三個供應商,平台的連線池有 200 個 worker。Little 定律算出使用中的 worker 數:每秒轉帳數 × 每筆佔住 worker 的秒數。

改之後:快速受理、背景結算、推送結果

使用者平台API 供應商Hibira開始使用服務處理中已寫入帳本,worker 釋放POST /transfers冪等鍵,從佇列送出202 Accepted已記錄,worker 釋放供應商從自己的佇列、以自己的步調結算transfer.settledprivate-partner-acmetransfer.settledid 123、金額balance.updatedprivate-wallet-42balance.updated
改之後:雙方都快速回應,結果以事件送達
  1. 平台先回應使用者。 把轉帳以「處理中」寫進帳本、放進佇列,然後回應。使用者的頁面顯示「處理中」,事件到達時自動更新。
  2. 由派送器把轉帳送給各供應商,帶冪等鍵、短逾時,而且每個供應商有固定數量的名額。供應商一記錄好轉帳就回 202,所以用同一個鍵重試永遠安全。
  3. 不要回呼。 請求本身帶齊供應商需要的一切並附上簽章,供應商不必回呼平台驗證。
  4. 結果用推送。 供應商把 transfer.settled 發佈到給該平台的私有頻道,例如 private-partner-acme。平台後端保持一條 WebSocket 連線並訂閱,由供應商的授權端點授權。平台更新帳本,再把 balance.updated 發佈到使用者的錢包頻道,做法同跨產品餘額同步。
  5. 用一次檢查補上遺漏。 平台每幾分鐘向每個供應商用一個批次請求查詢仍在處理中的轉帳,而不是逐筆輪詢。

供應商不穩時,平台照樣穩定

  • 每個供應商各有名額。 變慢的供應商只會佔滿派送器裡自己的名額。登入、儲值和其他供應商的 worker 都不受影響。
  • 供應商不回應就暫停送出。 連續逾時後,暫停該供應商的佇列,把它的服務顯示為暫時無法使用,等一下再試。轉帳停在你的帳本裡處於「處理中」,而不是卡在被佔住的連線上。
  • WebSocket 斷線不會擋住任何事。 轉帳照常受理。連線恢復後,批次檢查會把中間發生的都結算好。
  • 使用者從不等供應商的回應時間。 頁面以平台自己的速度回應,結果好了就會出現。

常見問題

為什麼一個慢的 API 供應商會拖慢整個平台?

因為平台的 worker 在等它。每個同步呼叫都會佔住一個 worker,直到供應商回應為止,而這些 worker 是和其他所有功能共用的。一個供應商變慢,worker 就被用光,連根本不碰那個供應商的請求也得排在後面。

WebSocket 會取代轉帳 API 嗎?

不會。轉帳本身仍是帶冪等鍵的 HTTP 請求,並記錄在雙方帳本裡。WebSocket 取代的是等待:被佔住的連線、狀態輪詢和回呼。結果改以事件送達。

轉帳完成時平台剛好斷線怎麼辦?

什麼都不會遺失,因為雙方帳本都已記下這筆轉帳。pusher-js 和其他用戶端函式庫會自動重新連線,處理中轉帳的批次檢查會結算任何漏掉的部分。用轉帳 ID 忽略已經套用過的事件。

這需要多少條連線?

平台後端到每個供應商的頻道各一條 WebSocket 連線,就足以處理與該供應商的所有轉帳,不論服務多少使用者。在 Hibira 上每次發佈算一則訊息;付費方案不計算送給訂閱者的份數。請看價格。

產品名稱為其所有者的商標。