防止用戶端停止回應
用戶端有兩種方式可以停止回應:網路連線可能會導致伺服器要求遺失,或伺服器本身可能會當機。 使用預設選項時,RPC 永遠不會逾時呼叫,而且您的用戶端執行緒會永遠等候回應。
有兩種方法可避免這種情況:保持運作和逾時。
TCP Keep Alives
用戶端可以設定為定期 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 呼叫開啟保持運作。
想要將保持運作設定為最低值,以確保用戶端應用程式及時回應網路問題。 應仔細考慮這類引人意,並仔細檢查是否保證有積極價值。 一旦還原連線之後,暫時失去連線的伺服器可能會發現從許多用戶端保持運作時,其本身會持續運作。 此外,較長的計算工作可能需要兩分鐘以上,而且伺服器可能會花費更多 CPU 時間回答保持運作,而不是執行有用的工作。 因此,保持運作應該與仲裁搭配使用。 如果用戶端無法容許其執行緒長時間系結,則應該考慮非同步 RPC。
根據所使用的傳輸,其他通訊協定序列可能會實作不同的機制來偵測沒有回應的伺服器。 ncalrpc傳輸不會使用 keep alives。 由於 ncalrpc 中的所有通訊都是本機的,如果伺服器在進行中呼叫時變得沒有回應,用戶端上的 RPC 執行時間會立即失敗呼叫。
通話逾時
如果網路連線中斷,或伺服器當機,TCP 保持運作會正常。 但是,如果伺服器在使用者模式中死結,TCP 保持運作會成功傳回,但呼叫永遠不會傳回。 為了處理此案例,已為 Windows XP 新增新的執行時間選項:RPC_C_OPT_CALL_TIMEOUT。 此選項會指示 RPC 執行時間在每次將要求傳送至伺服器時設定計時器。 如果計時器到期,則會自動取消呼叫,並完成RPC_S_CALL_CANCELLED。 只要伺服器在指定的時間限制內回應,用戶端就不會取消呼叫。 這表示多重組呼叫可能需要超過逾時期間才能完成,因為伺服器的每個回應都會在逾時期間內收到,即使所有回應抵達的時間週期都超過逾時期間。
此外,當呼叫取消時,伺服器不會收到取消的通知。 因此,伺服器可能會在某些時間點執行呼叫,而用戶端只會忽略來自伺服器的回應。
呼叫逾時最危險的陷阱是建立短暫逾時,並在相同伺服器上重試呼叫。 下列案例說明此方法的危險:
想像一部接近容量的伺服器。 其有許多用戶端具有非常短的逾時,例如五秒。 路由器的網路連線或壅塞暫時遺失會導致伺服器回復中斷幾秒鐘。 在乙太網路網路上,這種情況很容易是因為伺服器與另一部電腦共用的連結上的活動暴增所造成。 伺服器不會管理在五秒逾時之前傳送所有回復。用戶端會取消呼叫,然後立即重試。 伺服器不知道呼叫是重試的,也會執行這些呼叫。 因此,它會根據用戶端逾時數目執行 30-50% 的呼叫,而不是執行其一般呼叫工作負載。如果超過其容量,而且伺服器無法在五秒內回應所有用戶端,則會將另一輪呼叫傳送至伺服器。 用戶端會繼續重新發出相同的呼叫,因為伺服器已多載處理先前的呼叫,所以無法在逾時內回應。回應之後,用戶端就會叫用逾時、發出新的呼叫,並捨棄答案。 在最糟的情況下,伺服器在重新開機之前不會復原,而且視用戶端存取模式而定,在停止足夠的用戶端之前可能無法復原。
注意
呼叫逾時僅適用于 ncacn_ip_tcp 和 ncacn_HTTP 通訊協定序列。