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