클라이언트 쪽 중단 방지
클라이언트가 중단될 수 있는 두 가지 방법이 있습니다. 네트워크 연결로 인해 서버 요청이 손실되거나 서버 자체가 충돌할 수 있습니다. 기본 옵션을 사용하면 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 매개 변수와 시간 제한 값 간의 매핑을 초 단위로 변경할 수 있습니다.
시간 제한 매개 변수 | 실제 시간 제한(초) |
---|---|
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) | 무한 시간 제한 |
활성 유지가 켜지면 클라이언트는 1초마다 1개의 keep alive 패킷을 보냅니다. 서버에서 3개 이상의 연결 유지에 대한 승인이 없는 경우 클라이언트는 연결이 멸망됨을 선언하고 원격 프로시저 호출에 실패합니다. 서버가 지정된 시간 제한 내에 응답을 보내는 경우 활성 유지가 켜지지 않습니다. 서버가 활성 상태로 유지에 응답하지만 원격 프로시저 호출에 응답하지 않는 경우 클라이언트는 계속 유지를 활성 상태로 보냅니다. 서버가 RPC 호출에 응답하면 활성 유지가 꺼집니다. Windows 2000의 경우 활성 유지는 동기 RPC 호출에 대해서만 설정됩니다. Windows XP의 경우 비동기 RPC 호출에도 활성 유지가 설정됩니다.
클라이언트 애플리케이션이 네트워크 문제에 적시에 응답할 수 있도록 유지를 가장 낮은 값으로 설정하는 것이 좋습니다. 이러한 유혹에 주의 깊게 고려해야 하며 공격적인 가치가 보장되는지 여부에 대한 조사가 적용되어야 합니다. 연결이 일시적으로 끊어지는 서버는 연결이 복원되면 수많은 클라이언트에서 활성 상태로 유지되어 넘쳐나게 될 수 있습니다. 또한 긴 계산 작업은 2분 이상 걸릴 수 있으며 서버는 유용한 작업을 수행하는 것보다 CPU 응답에 더 많은 CPU 시간을 소비할 수 있습니다. 따라서 활성 유지는 조정과 함께 사용해야 합니다. 클라이언트가 스레드가 장기간 연결되는 것을 허용할 수 없는 경우 비동기 RPC를 고려해야 합니다.
다른 프로토콜 시퀀스는 사용되는 전송에 따라 응답하지 않는 서버를 검색하기 위한 다양한 메커니즘을 구현할 수 있습니다. ncalrpc 전송은 유지를 사용하지 않습니다. ncalrpc의 모든 통신은 로컬이므로 호출이 진행되는 동안 서버가 응답하지 않으면 클라이언트의 RPC 런타임이 즉시 호출에 실패합니다.
통화 시간 초과
네트워크 연결이 끊어지거나 서버가 충돌하는 경우 TCP 유지는 괜찮습니다. 그러나 서버가 사용자 모드에서 교착 상태인 경우 TCP 유지는 성공적으로 반환되지만 호출은 반환되지 않습니다. 이 시나리오를 처리하기 위해 Windows XP: RPC_C_OPT_CALL_TIMEOUT 대한 새 런타임 옵션이 추가되었습니다. 이 옵션은 RPC 런타임에 서버에 요청을 보낼 때마다 타이머를 설정하도록 지시합니다. 타이머가 만료되면 호출이 자동으로 취소되고 RPC_S_CALL_CANCELLED 완료됩니다. 서버가 지정된 시간 제한 내에 응답하는 한 클라이언트는 호출을 취소하지 않습니다. 즉, 모든 응답이 도착하는 기간이 시간 제한 기간을 초과하더라도 서버의 각 응답이 시간 제한 기간 내에 수신되므로 다중 인프라 호출이 완료되는 데 시간 제한 기간보다 더 많은 시간이 걸릴 수 있습니다.
또한 호출이 취소되면 서버에 취소 알림이 표시되지 않습니다. 따라서 서버는 특정 시점에 호출을 실행할 가능성이 높으며 클라이언트는 서버의 응답을 무시합니다.
통화 시간 초과로 가장 위험한 문제는 짧은 시간 초과를 설정하고 동일한 서버에서 통화를 다시 시도하는 것입니다. 다음 시나리오에서는 이 방법의 위험을 보여 줍니다.
용량 근처에서 작동하는 서버를 상상해 보십시오. 5초와 같이 매우 짧은 시간 제한으로 많은 클라이언트가 있습니다. 라우터에서 네트워크 연결 또는 정체가 일시적으로 손실되면 서버 회신이 몇 초 동안 경과됩니다. 이더넷 네트워크에서 이 상황은 서버가 다른 컴퓨터와 공유하는 링크에서 활동이 급증하여 쉽게 발생할 수 있습니다. 서버는 5초 제한 시간 전에 모든 회신을 보낼 수 없습니다. 클라이언트는 호출을 취소하고 즉시 다시 시도합니다. 서버는 호출이 다시 시도된다는 것을 인식하지 못하고 이를 실행합니다. 따라서 일반적인 호출 워크로드를 실행하는 대신 시간 초과된 클라이언트 수에 따라 30~50% 더 많은 호출을 실행합니다. 이 값이 용량을 초과하고 서버가 5초 이내에 모든 클라이언트에 응답할 수 없는 경우 다른 호출 라운드가 서버로 전송됩니다. 클라이언트는 동일한 호출을 계속 재발행하며, 서버가 이전 호출을 처리하는 오버로드되었으므로 시간 초과 내에 응답할 수 없습니다. 응답하면 클라이언트가 시간 초과에 도달하고, 새 호출을 실행하고, 응답을 삭제했습니다. 최악의 경우 서버는 다시 부팅될 때까지 복구되지 않으며 클라이언트 액세스 패턴에 따라 충분한 수의 클라이언트가 중지될 때까지 복구되지 않을 수 있습니다.
참고
호출 시간 제한은 ncacn_ip_tcp 및 ncacn_http 프로토콜 시퀀스에서만 작동합니다.