製作透過任何 SDK 與 Azure Cosmos DB 互動的用戶端應用程式時,請務必了解幾個重要的基本概念。 本文是一個設計指南,可協助您了解這些基本概念,並設計復原性應用程式。
如需本文所討論概念的概觀影片,請參閱:
連線模式
Azure Cosmos DB SDK 可以用兩種連線模式中連線至服務。 .NET 和 Java SDK 可以在 閘道 或 直接 模式中連線到服務,而其他 SDK 則只能在閘道模式中連線。 網關模式會使用 HTTP 通訊協定,而直接模式通常會使用 TCP 通訊協定。
網關模式一律用來擷取元數據,例如帳戶、容器和路由資訊,而不論已設定使用哪一種模式 SDK。 此資訊會快取至記憶體中,並用來連線到服務複本。
總而言之,針對網關模式中的 SDK,您可以預期 HTTP 流量,而在直接模式的 SDK 中,您可以在不同的情況下預期 HTTP 和 TCP 流量的組合,例如初始化、擷取元數據或路由資訊。
用戶端執行個體和連線
無論連線模式為何,維護每個應用程式每個帳戶的 SDK 用戶端單一資料庫執行個體非常重要。 HTTP 和 TCP 的連線範圍都限於用戶端執行個體。 大部分的計算環境在可以同時開啟的連線數目方面都有限制。 達到這些限制時,連線就會受到影響。
分散式應用程式和網路
當您設計分散式應用程式時,包含三個主要元件:
- 您的應用程式及其執行環境
- 網路,其中包含應用程式與 Azure Cosmos DB 服務端點之間的任何元件
- Azure Cosmos DB 服務端點
發生失敗時,原因通常來自這三個區域之一,而且請務必了解,由於系統的分散式本質,因此無法預期這些元件有 100% 的可用性。
Azure Cosmos DB 有一組完整的可用性 SLA,但其中沒有任何一個 SLA 的可用性為 100%。 將應用程式連線到服務端點的網路元件可能會發生暫時性硬體問題,並遺失封包。 即使是應用程式執行所在的計算環境,也可能出現影響作業的 CPU 尖峰。 這些失敗狀況可能會影響 SDK 的作業,並通常顯示為特定程式碼的錯誤。
透過對 SDK 所提供的回應實作重試原則,您的應用程式應可從這些元件中特定程度的潛在失敗中復原。
我的應用程式應該針對錯誤重試嗎?
簡短的答案是 是的,但並非所有錯誤都可以重試。 某些錯誤或狀態代碼不是暫時性的。 下表詳細說明它們:
| 狀態碼 | 應該新增重試 | SDK 重試 | Description |
|---|---|---|---|
| 400 | 否 | 否 | 不正確的要求 |
| 401 | 否 | 否 | 未獲授權 |
| 403 | 可選 | 否 | 禁止 |
| 404 | 否 | 否 | 找不到資源 |
| 408 | Yes | Yes | 要求逾時 |
| 409 | 否 | 否 | 衝突失敗是指當寫入作業中提供的資源識別碼和分區鍵已被現有資源使用,或當違反唯一鍵條件時發生。 |
| 410 | Yes | Yes | 消失例外狀況 (不違反 SLA 的暫時性失敗) |
| 412 | 否 | 否 | 前置條件失敗是指作業指定的 eTag 與伺服器上可用的版本不一致。 這屬於開放式同步存取錯誤。 讀取最新版的資源及更新要求上的 eTag 之後,重試要求。 |
| 413 | 否 | 否 | 請求資料太大 |
| 429 | Yes | Yes | 針對 429 可放心執行重試。 請參閱指南以針對 HTTP 429 進行疑難排解。 |
| 449 | Yes | Yes | 這是只有寫入作業才會發生的暫時性錯誤,可放心執行重試。 這可能代表有設計上的問題,導致過多並行作業嘗試更新 Azure Cosmos DB 中的相同物件。 |
| 500 | 否 | 否 | 發生預期外的伺服器錯誤而導致作業失敗。 請提出 Azure 支援問題來連絡支援人員。 |
| 503 | Yes | Yes | 服務無法使用 |
第二個數據行中標示為 [是 ] 的所有狀態代碼都應該在應用程式中具有某種程度的重試涵蓋範圍。
HTTP 403
一般而言,Azure Cosmos DB SDK 不會在 HTTP 403 失敗時重試,但某些與 HTTP 403 相關聯的錯誤可能會導致您的應用程式做出反應。 例如,如果您收到錯誤指出 分割區索引鍵已滿,您可能會決定根據某些業務規則更改您要寫入的文件的分割區索引鍵。
HTTP 429
根據客戶端的設定,Azure Cosmos DB SDK 預設會在遇到 HTTP 429 錯誤時重試。它會遵循服務的響應 x-ms-retry-after-ms 標頭,先等候指定的時間,然後再進行重試。
當超過 SDK 重試次數時,錯誤會傳回至您的應用程式。 在理想情況下,檢查回應中的 x-ms-retry-after-ms 標頭可作為提示,以決定重試要求之前等待的時間長度。 另一個替代方法是指數回退演算法,或設定用戶端針對 HTTP 429 延長重試次數。
HTTP 449
Azure Cosmos DB SDK 會在 HTTP 449 上進行重試,並在固定時間內以累進退避策略以因應大部分案例。
當超過自動 SDK 重試時間上限時,錯誤會傳回至您的應用程式。 HTTP 449 錯誤可以安全地重試。 由於寫入作業具有高度並行性質,因此最好採用隨機退避演算法,以避免在固定間隔之後重複相同程度的並行。
逾時和連線相關失敗 (HTTP 408/503)
網路逾時和連線失敗是最常見的錯誤之一。 Azure Cosmos DB SDK 本身具有復原性,如果重試可行,則會在 HTTP 和 TCP 通訊協定上針對逾時和連線問題進行重試:
- 針對讀取作業,SDK 會重試任何逾時或連線相關錯誤。
- 針對寫入操作,SDK 不會重試,因為這些操作 不是等冪操作。 如果等候回應時發生逾時,則無法知道要求是否已到達服務。
如果帳戶有多個可用區域,SDK 也會嘗試 跨區域重試。
由於逾時和連線失敗的特性,這些錯誤可能不會出現在您的帳戶計量中,因為計量只包含服務端發生的失敗。
建議應用程式針對這些案例設定專屬的重試原則,並考慮如何解決寫入逾時。 例如,若在建立操作逾時時重試,且先前的請求確實到達服務端,則可能會返回 HTTP 409(衝突);但如果先前的請求沒有到達服務端,則重試會成功。
語言特定的實作詳細數據
如需語言的相關實作詳細數據,請參閱:
重試是否會影響延遲?
從客戶端的觀點來看,任何重試都會影響作業的端對端延遲。 當應用程式 P99 延遲受到影響時,了解目前的重試以及這些問題的解決方法很重要。
Azure Cosmos DB SDK 會在其記錄和診斷中提供詳細資訊,以協助識別正在進行哪些重試。 如需詳細資訊,請參閱 .NET SDK 和 Java SDK 的診斷資訊。
如何減輕重試延遲?
視 情況而定,在大部分情況下,SDK 會將要求路由傳送至本機區域、寫入區域(在單一區域寫入案例中),或 慣用區域 清單中的第一個區域。 此優先順序主要會連線到最接近或最理想的資料中心,將狀況良好案例中的延遲降到最低。
不過,此優先順序也意味著,在特定錯誤情境下,可能會導致失敗的請求總是先在一個特定區域中嘗試。 如果該案例中偏好容錯移轉至另一個區域,這通常就會在基礎結構 (流量管理員) 層處理,而不是在 SDK 層級處理。 基礎結構的適當設定和設定可確保在區域性中斷期間有效率地重新路由傳送流量,以減輕中斷案例中跨區域重試的延遲。 如需設定基礎結構層級容錯移轉的詳細資訊,請參閱 Azure 流量管理員文件。 某些 SDK 支援直接在 SDK 層級實作類似的容錯移轉策略。 例如,請參閱 Java SDK 和 .NET SDK 的高可用性。
什麼是區域停電呢?
Azure Cosmos DB SDK 具備區域可用性,並可在另一個帳戶區域上執行重試。 若要瞭解哪些案例涉及其他區域,請參閱 多區域環境重試案例和設定。
何時應連絡客戶支援
在連絡客戶支援之前,請先執行下列步驟:
- 受影響的作業量相較於成功作業的量度結果如何? 是否符合服務 SLA 的要求?
- P99 延遲是否受到影響?
- 失敗是否與我的應用程式應重試的錯誤碼有關,並且應用程式是否涵蓋這些重試?
- 失敗會影響所有應用程式執行個體還是只會影響子集? 當問題縮減為執行個體的子集時,通常是與這些執行個體相關的問題。
- 您是否已完成上表中的相關疑難解答檔,以排除應用程式環境的問題?
如果所有應用程式執行個體都受到影響,或受影響的作業百分比超出服務 SLA 範圍,或影響您自己應用程式的 SLA 和 P99,請聯絡客戶技術支援。