共用方式為


處理連線中斷

RPC 呼叫完成之後,不會關閉連線;它標示為免費。 因此,伺服器可能會當機或失去網路連接,可能發生在通話期間或之間,當連線停留在集區中時。 就原則而言,只有在符合下列兩個條件時,RPC 運行時間才會重新嘗試這些呼叫:

  • 伺服器無法執行呼叫,或呼叫是具冪等性。
  • 用戶端可以以高效效能的方式實作重試。

下列段落會展開並釐清這兩個條件。

等冪呼叫是在伺服器上可以多次執行的呼叫,而不會產生不想要的副作用。 例如,在銀行中查詢指定帳戶餘額的 RPC 呼叫具有等冪性。 如果因為連線中斷而執行此呼叫兩次,則不會造成任何傷害。 另一個等冪呼叫範例是變更資料庫中客戶的位址。 執行兩次沒問題,因為第二次執行只會以相同的位址取代已經目前的位址。 「從帳戶 xyz 減去五十美元」這類操作不是冪等的。 網路連線中斷不應造成這類呼叫的多次執行。

出於安全考量,RPC 執行時期會將所有呼叫視為非等冪操作。 ncacn_ip_tcp不支援 [等冪] 屬性,而且會被忽略。 因此,前述清單中的第一個條件簡化為無法執行呼叫的伺服器

在許多情況下,RPC 執行環境無法明確判定呼叫是否已在伺服器上執行過。 在這種情況下,用戶端將不會重試執行呼叫。

下列範例說明 RPC 執行階段時期何時會重試呼叫以及何時不會:

  • 伺服器重新啟動。

    重新啟動後,在之前未進行呼叫的介面上,進行了一次無安全性 RPC 呼叫。 由於此介面上沒有呼叫,RPC 執行階段會首先嘗試協商使用此介面。 它會使用集區中的連線來傳送封包。 由於伺服器重新啟動,且連線不再有效,因此會傳回錯誤。 由於用戶端 RPC 執行時間尚未開始傳送實際呼叫的數據,因此用戶端會判斷伺服器可能無法在這些數據上執行。 因此,它會關閉連線,並在集區中尋找另一個連線。 如果找不到連線,則會開啟新的連線,並嘗試再次交涉使用 介面。 如果成功,就會進行呼叫(也就是說,因為在呼叫啟動之前就偵測到了失敗,所以進行重試)。

  • 具隱私層級安全性(加密)的 RPC 呼叫是在已協商的安全性上下文的連線上進行。

    為了確保高效能,RPC 執行時會將封送處理包內嵌加密(透過明文數據)。 如果嘗試傳送數據失敗,RPC 運行時間就無法重試呼叫,因為純文本數據已被加密的數據覆寫,而且無法以新的安全性內容重新加密數據。 因此,不會重試。

  • 傳送非第一個資料片段會失敗。

    不會重試,因為 RPC 運行時間可能會選擇在完成之後捨棄第一個片段的內容,而且無法重試傳送第一個片段。

  • RPC 要求已傳送。

    伺服器中止連接。 未嘗試重試,因為 RPC 無法辨別伺服器是否收到呼叫並開始執行它。

如果伺服器使用動態端點,RPC 將不會在重試期間重新解析端點。 這表示如果伺服器被關閉後重新啟動,它可能會在不同的端點上,而在重試呼叫時,RPC 不會自動重新解析端點。 若要強制重新解析端點,RPC 用戶端應該先呼叫 RpcBindingReset,再重試呼叫。

在這些案例中,如果 RPC 用戶端可以判斷呼叫是否具有等冪性,或者如果它保留 RPC 捨棄的數據,它可能會選擇在 RPC 之上建立重試機制。

注意

如果伺服器是叢集,且叢集的不同節點會執行不同版本的伺服器軟體,則 RPC 重試可能會在故障轉移時將呼叫登陸叢集的不同節點上,而且可能位於不同版本的伺服器上。 在這類部署案例中,請確定用戶端不會依賴特定版本的伺服器軟體來執行指定的呼叫。 如果這樣做,客戶端應該在 RPC 之上建置機制,以偵測並處理這類條件。