您的用戶端有兩種方式可以停止回應:網路連線可能會導致伺服器要求遺失,或伺服器本身可能會當機。 使用預設選項時,RPC 永遠不會逾時呼叫,而且您的用戶端線程會永遠等候回應。
有兩種方法可以防止這種情況:保持活性和超時。
TCP 保持運作
您可以設定用戶端定期 Ping 伺服器,以確保伺服器運作且正在執行。 Ping 是 ncacn_ip_tcp 和 ncacn_http 通訊協定序列的 TCP 保持連線,因此在 CPU 使用率和網路頻寬方面效率很高。 若要在給定的遠端程序呼叫上啟用保持連線,請在呼叫開始之前,使用 RpcMgmtSetComTimeout 函式。 此函式會採用系結句柄和逾時作為自變數。 在 RpcMgmtSetComTimeout 設定超時後,這個綁定句柄上的每次遠端過程調用都使用提供的超時設定。
RpcMgmtSetComTimeout 函式的 Timeout 參數會指定 RPC 運行時間在開啟保持運作之前等候的時間長度。 逾時是介於 0 到 10 之間的值,其中 0 是最短逾時,而 10 是無限逾時(沒有逾時)。 逾時的單位本身並非以秒為單位;從提供給 RpcMgmtSetComTimeout 函式的逾時值轉換為秒的過程是由 RPC 運行時間完成,且取決於具體實作。
下表提供 Windows 2000 和 Windows XP 的轉譯秒數。 未來的 Windows 版本可能會變更 Timeout 參數與逾時值之間的對應,以秒為單位:
| Timeout 參數 | 實際逾時以秒為單位 |
|---|---|
| 0 (RPC_C_BINDING_MIN_TIMEOUT) | 120 |
| 1 | 240 |
| 2 | 360 |
| 3 | 480 |
| 4 | 600 |
| 5(RPC_C_BINDING_DEFAULT_TIMEOUT) | 720 |
| 6 | 840 |
| 7 | 960 |
| 8 | 1080 |
| 9 (RPC_C_BINDING_MAX_TIMEOUT) | 1200 |
| 10 (RPC_C_BINDING_INFINITE_TIMEOUT) | 無限逾時 |
開啟保活功能後,用戶端會每秒傳送一個保活封包。 如果伺服器沒有確認有三個以上的保持運作狀態,用戶端會宣告連線已失效,並失敗遠端過程調用。 如果伺服器在指定的逾時範圍內傳送回應,則不會啟用保持連線功能。 如果伺服器回應保持連線,但不回應遠程程序呼叫,用戶端會繼續傳送保持連線。 一旦伺服器回應 RPC 呼叫,保持運作就會關閉。 對於 Windows 2000,僅在同步 RPC 呼叫時啟用保持連線。 針對 Windows XP,也會為異步 RPC 呼叫開啟保持連線功能。
將 keep-alive 設置為最低值可能很有誘惑力,這樣可以確保客戶端應用程式能及時響應網路問題。 應仔細考慮這種誘惑,並仔細審查是否有必要採取激進的價值。 當伺服器暫時失去連線後再次恢復時,可能會發現自己被大量的用戶端保持連線信號淹沒。 此外,長時間的計算工作可能需要超過兩分鐘的時間,而且伺服器可能會發現自己花費更多的 CPU 時間回答保持運作,而不是執行有用的工作。 因此,保持運作應該適度使用。 如果客戶端無法容忍其執行緒長時間被占用,則應考慮使用異步 RPC。
其他通訊協定順序可能會實作不同的機制來偵測沒有回應的伺服器,視所使用的傳輸而定。 ncalrpc 傳輸不會使用保持運作。 由於 ncalrpc 中的所有通訊 都是本地的,如果伺服器在呼叫進行時變得無回應,客戶端上的 RPC 運行時會立即中斷呼叫。
通話暫停
如果網路連線中斷,或伺服器當機,TCP 保持連線機制是可行的。 但是,如果使用者模式中的伺服器死結,TCP 保持連線會成功傳回,但呼叫仍然不會傳回。 為了處理此案例,Windows XP 已新增新的運行時間選項:RPC_C_OPT_CALL_TIMEOUT。 此選項會指示 RPC 執行階段在每次將要求傳送至伺服器時設定計時器。 如果定時器到期,系統會自動取消呼叫,並完成RPC_S_CALL_CANCELLED。 只要伺服器在指定的時間限制內回應,用戶端就不會取消呼叫。 這表示多部門呼叫可能需要超過逾時期間才能完成,因為伺服器的每個回應都會在逾時期間內收到,即使所有到達回應的時間週期都超過逾時期間。
此外,當呼叫取消時,伺服器不會收到取消的通知。 因此,伺服器可能會在某些時間點執行呼叫,而用戶端只會忽略伺服器的回應。
呼叫逾時最危險的陷阱之一是設定較短的逾時時間,並在相同伺服器上重試呼叫。 下列案例說明此方法的危險:
想像一下運作接近容量的伺服器。 它有多個客戶端,其超時時間非常短,例如五秒。 路由器的網路連線暫時中斷或壅塞會導致伺服器回應中斷幾秒鐘。 在乙太網路網路上,這種情況很容易是因為伺服器與另一部計算機共用的連結上活動暴增所造成。 伺服器未能在五秒超時之前傳送所有回應。客戶端的呼叫被取消,然後立即重試。 伺服器不知道呼叫是重試的,也會執行這些呼叫。 因此,根據用戶端逾時數目,它會執行 30-50% 更多呼叫,而不是執行其一般呼叫工作負載。如果超過其容量,而且伺服器無法在五秒內回應所有用戶端,則會將另一輪呼叫傳送至伺服器。 用戶端會繼續重新發出相同的呼叫,而且由於伺服器已多載處理先前的呼叫,因此無法在逾時內回應。一旦回應,用戶端就會達到逾時、發出新的呼叫,並捨棄答案。 在最壞的情況下,伺服器在重新啟動之前不會復原,而且視用戶端存取模式而定,在停止足夠數量的用戶端之前可能無法復原。
注意
呼叫逾時僅適用於 ncacn_ip_tcp 和 ncacn_http 通訊協定序列。