Microsoft MVP성태의 닷넷 이야기
.NET Framework: 97. WCF : netTcpBinding에서의 각종 Timeout 값 설명 [링크 복사], [링크+제목 복사],
조회: 32279
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 3개 있습니다.)

WCF : netTcpBinding에서의 각종 Timeout 값 설명


WCF 서비스를 참조하게 되면, 클라이언트 측의 app.config에 제법 많은 설정값들이 구성됩니다. 처음에는 당황스러울 정도인데요. 오늘은 그중에서 "netTcpBinding"에서 제공되는 "closeTimeout", "openTimeout", "receiveTimeout", "sendTimeout", "inactivityTimeout" 값들에 대해서 알아보도록 하겠습니다. (참고로, 여기서 제공되는 값들에 대한 설명은 "Session이 설정된 netTcpBinding" 서비스인 경우로 가정하겠습니다.)




1. openTimeout, closeTimeout
이 값들은, 서로 대칭적인 의미를 가지기 때문에 한꺼번에 설명해 보도록 하겠습니다. 사실, 어찌 보면 설명할 것도 없지요. 이름에서 의미하듯이 서비스가 열리고/닫히는 순간에 필요 이상의 시간이 소모되는 것을 막을 수 있도록 해주는 값입니다.

openTimeout/closeTimeout 값은 모두 기본값이 1분으로 설정되어 있습니다. 의미인 즉, 클라이언트에서 서비스에 접속하려고 할 때, 만약 서비스를 호스팅하고 있는 서버가 죽어 있는 경우에 "1분" 동안 클라이언트 측의 호출 쓰레드가 "Blocking" 된다는 것입니다. 별로 바람직하지는 않죠! 약 3 ~ 10초 정도면 적당할 거라 봅니다.

하지만, 한편으론 시간을 너무 줄이는 것은 주의해야 합니다. .NET의 경우 JIT 컴파일링이 메서드 호출 시에 이뤄지다 보니, 최초 접속 시에는 서비스가 올라오기까지 시간이 좀 걸리기 때문에 openTimeout을 너무 짧게 잡아버리면 예외가 발생하는 경우도 생길 수 있습니다.

closeTimeout의 경우, WCF 연결이 된 상태에서 네트워크 선을 뽑은 후 System.ServiceModel.ClientBase<>.Close 메서드를 호출하게 되면 closeTimeout에 지정된 시간만큼 블록킹이 발생한 후 TimeoutException이 발생하게 됩니다.

부연 설명을 더 드리자면, 항상 정확하게 openTimeout/closeTimeout에 지정된 시간만큼의 지연이 발생하지는 않는다는 점에 유의하셔야 합니다. openTimeout 값을 10분으로 설정했다고 해서, System.ServiceModel.ClientBase<>.Open 메서드가 존재하지도 않은 IP 또는 포트에 대해 10분을 꽉 채운 후에 제어가 반환되는 것은 아닙니다. 즉, 10분으로 설정했어도 35초 만에 Open 메서드 호출이 실패해서 반환될 수 있습니다.

2. sendTimeout
이 값 역시, 어느 정도 의미가 와 닿지요. 특정 메서드를 호출할 때 지정된 sendTimeout 시간 이내에 메서드 실행이 완료되지 않으면 TimeoutException 이 발생하게 됩니다. 재미있는 것은 이것이 서버 측 EXE의 config 내에 있을 때는, 콜백 함수의 실행 시간을 나타내고, 클라이언트 측 EXE의 config 내에 있을 때는 서비스가 제공하는 메서드를 호출하는 시간 만료에 대한 의미를 가집니다.

3. receiveTimeout
이 값은, 정확하다고는 말할 수 없지만 클라이언트에서는 설정 자체에 대한 아무런 의미가 없는 것 같습니다. 단지 서버 측에서 쓰일 때는 의미를 지닙니다. WCF 서비스는 지정된 receiveTimeout 시간 내에 클라이언트로부터 아무런 메서드 호출이 없으면, 설령 클라이언트가 정상적으로 연결되어져 있다 하더라도 접속을 끊어버리는 데에 이 값을 사용하고 있습니다. 그러니까, 만약 이 값을 5초로 설정했다면 반드시 5초 이내에는 해당 서비스에서 제공되는 메서드를 호출해 주어야 서버와의 연결을 지속적으로 유지할 수가 있습니다.

'꼭 기억해 두십시오. 연결이 맺어져 있는 경우라 할지라도 지정된 시간 동안 서비스를 사용하고 있지 않으면 강제로 연결을 끊어버린다는 것.'

4. inactivityTimeout
마지막으로 설명할 이 값은, 특이하게도 reliableSession 요소의 속성값으로 존재합니다. 이 값은, 지정된 시간 동안 상대방에 대해 연결을 확인할 수 없으면 강제로 현재의 연결 개체를 끊어버리도록 해줍니다.

일례로, 서로 WCF 연결 관계를 맺고 있는 2대의 컴퓨터가 있다고 가정할 때. 어느 하나의 컴퓨터에서 랜선을 뺀다거나, 컴퓨터 전원 플러그를 강제로 뽑는다거나, 작업 관리자에서 WCF 프로세스를 강제로 종료하는 등의 경우에 inactivityTimeout 값이 위력을 발휘하기 시작합니다. 만약 이 값이, WCF 서비스 측에 5초로 설정되어 있다면, 클라이언트 프로세스를 작업관리자로 강제 종료시키고 약 5초 후에 서비스 측에서의 연결 개체도 회수되는 것을 확인할 수 있습니다. (바로 이때 불려지는 이벤트를 지난 회에 설명 드린 OperationContext.Current.Channel.Faulted로 잡아낼 수 있습니다.) 물론, 반대로 클라이언트 프로세스에 이 값이 10초로 지정되어 있다면, 서버 측 서비스가 10초 동안 아무런 응답도 할 수 없는 상황에 놓이면 예외가 발생하게 되어 클라이언트가 이를 감지할 수 있습니다.

좀 정리가 되시나요? 가만 보면, .NET Remoting에서 사용되던 Lease Manager 개념과 많이 비슷한 것을 볼 수 있습니다. 한 가지 더 참고로 말씀드리면, sendTimeout, receiveTimeout, inactivityTimeout 등의 값을 너무 짧게 잡으면 VS.NET에서 디버깅 시에 쪼끔 괴롭습니다. (BP 걸고 한 라인씩 코드 실행해 보는 동안 연결이 강제로 끊겨 버립니다.)




마지막으로 한 가지 더! 서버의 비정상 종료에 의해 클라이언트 측에서 발생하는 예외에 관련된 부분을 언급해 보겠습니다.

대개의 경우, sendTimeout에 지정된 시간 동안 메서드 완료가 안되면 거의 서버가 종료되었다고 봐도 무방한 경우가 있을 것입니다. 이런 경우에는 특히 inactivityTimeout 값을 잘 설정해 주어야 합니다.

예를 들어, 다음의 경우를 보겠습니다.

while ( true )
{
   try {
     svc.DoMethod(); // 서비스에서 제공되는 오퍼레이션 호출
     Thread.Sleep( 1000 );
   } catch (TimeoutException ex)
   {
   } catch (CommunicationException ex)
   {
   }
}

위와 같은 상황에서, 어느 순간 대상이 되는 서비스를 강제 종료를 하게 되면, 곧이어 발생하는 메서드 호출에서 sendTimeout 시간 동안 응답을 받지 못해 TimeoutException이 발생하게 됩니다. 바로 여기서부터 문제가 발생됩니다. 만약 이때, inactivityTimeout 값이 1분이고 sendTimeout 값이 5초라면, 1분 동안 계속해서 5초마다 TimeoutException이 발생하고 나서야 CommunicationException이 발생하게 되어 OperationContext.Current.Channel.Faulted 이벤트가 실행되어집니다.

대부분의 경우에 위와 같은 상황을 원하는 경우는 없을 것입니다. sendTimeout 내에 메서드 실행이 완료되지 않으면 서비스가 비정상 종료되었다고 판단하고 서비스 재접속을 시도하는 것이 바람직할 수 있습니다. 따라서, 이런 경우에는 inactivityTimeout == sendTimeout 값을 같게 설정하는 것도 고려해 볼 수 있겠습니다.



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 7/10/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2008-03-11 04시50분
kevin25
2008-04-11 08시52분
아울러, 각 바인딩에 따른 기본 보안 설정.
Default ProtectionLevel for Standard Bindings
; https://docs.microsoft.com/en-us/archive/blogs/drnick/default-protectionlevel-for-standard-bindings
kevin25
2008-12-03 02시00분
[WCF] netTcpBinding를 사용해서 서비스를 구현해보았습니다.
receiveTimeout의 기본값이 10분이라고 하는데... 이 서비스를 10분이아닌 서버가 살아있는 동안(즉 메세지를 수신하지 않터라도) 연결을 유지할수 있는 방법이 있는지
알고 싶습니다.
MSDN에 보니 InactivityTimeout값 또한 같이 변경해야하는것 같은데 아직 초보라 조언을 구해봅니다.
아.. 하나더 여쭤보면 reliableSession의 enabled속성에 대해서도 설명부탁드릴께요.. 감사합니다.
[guest]
2008-12-03 04시38분
[WCF] 바로 위에 질문한 사람입니다.
Client를 2개 이상 띄워 놓고 통신하다가 1개의 접속을 끈으면 접속이 끈키더라구요.
InactivityTimeout때문인것도 같고... 아님 다른건가??
시간이 나신다면... 답변 달아주세요 ^^
감사합니다.
[guest]
2008-12-04 09시17분
일단, 메시지를 수신하지 않더라도 연결을 유지하고 싶다면, 그냥 단순히 DateTime이 가질 수 있는 최대값을 주면 될 것 같습니다. 10년 기간을 설정할 수 있다 해도 충분하지 않을까요? (설마, 10년 동안 윈도우즈 보안 패치를 받지는 않을 거란 말은 하지 말아주세요. ^^)

inactivityTimeout 값은 위에 설명해 드린 그대로인데요. 어떻게 더 설명을 드려야 할지?

그리고, reliableSession[@enabled = 'true']로 설정해 놓는 이유는 말 그대로 reliableSession을 사용하기 위해서이겠죠. 그리고, 그래야만 Ordered, InactivityTimeout 값을 설정할 수 있겠고요. 좀 더 기술적인 부분은 다음의 토픽을 참고하십시오.

Windows Vista Technical Articles
Introduction to Reliable Messaging with the Windows Communication Foundation
; https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/aa480191(v=msdn.10)

그리고, 클라이언트는... 1개를 끊었는데, 다른 한개도 접속이 끊겼다는 것인가요? 구성하신 환경을 최대한 자세하게 설명해 주십시오. 저는 부채도사가 아닙니다. ^^
kevin25
2008-12-04 03시50분
[WCF] 제 질문에 소중한 시간 내주셔서 우선 감사의 말씀올림니다.. (__) 꾸벅
저도 자세하게 설명드릴려고 했는데... 쓰다보니 말이 꼬이더라구요 ;;
답변내용을 보고 다시한번 매진하고 있습니다..
다시 질문 드리게 된다면 자세한 설명 붙이겠습니다.
날이 많이 추워졌는데 감기도 조심하시구요
[guest]
2010-12-08 10시41분
Hosting in IIS using NetTcpBinding
; (broken) http://blogs.msdn.com/b/james_osbornes_blog/archive/2010/12/07/hosting-in-iis-using-nettcpbinding.aspx
정성태
2011-10-10 11시46분
WCF - 서버측에서의 유효한 Timeout 설정
; http://www.sysnet.pe.kr/2/0/1144
정성태
2011-10-10 11시48분
WCF 의 InactivityTimeout
; http://www.sysnet.pe.kr/2/0/898
정성태
2019-06-07 11시13분
[초보] 이거 클라이언트 로그인 시 이벤트로 OperationContext.Current.Channel.Closed, OperationContext.Current.Channel.Faulted 설정 하고 바인딩 시 receiveTimeout="infinite"주면 무한 대기 했다가 정상적으로 끊는걸 할 수 있지 않을까요???
[guest]
2019-06-07 01시13분
@초보 직접 해보시고 그 결과를 덧글로 달아주신다면 더 좋지 않을까요? ^^
정성태

... 91  92  93  94  95  96  97  [98]  99  100  101  102  103  104  105  ...
NoWriterDateCnt.TitleFile(s)
11484정성태4/11/201824743.NET Framework: 737. C# - async를 Task 타입이 아닌 사용자 정의 타입에 적용하는 방법파일 다운로드1
11483정성태4/10/201828044개발 환경 구성: 358. "Let's Encrypt"에서 제공하는 무료 SSL 인증서를 IIS에 적용하는 방법 (2) [1]
11482정성태4/10/201820487VC++: 126. CUDA Core 수를 알아내는 방법
11481정성태4/10/201832115개발 환경 구성: 357. CUDA의 인덱싱 관련 용어 - blockIdx, threadIdx, blockDim, gridDim
11480정성태4/9/201822169.NET Framework: 736. C# - API를 사용해 Azure에 접근하는 방법 [2]파일 다운로드1
11479정성태4/9/201817781.NET Framework: 735. Azure - PowerShell로 Access control(IAM)에 새로운 계정 만드는 방법
11478정성태11/8/201920028디버깅 기술: 115. windbg - 덤프 파일로부터 PID와 환경변수 등의 정보를 구하는 방법 [1]
11477정성태4/8/201817474오류 유형: 460. windbg - sos 명령어 수행 시 c0000006 오류 발생
11476정성태4/8/201819038디버깅 기술: 114. windbg - !threads 출력 결과로부터 닷넷 관리 스레드(System.Threading.Thread) 객체를 구하는 방법
11475정성태3/28/201821338디버깅 기술: 113. windbg - Thread.Suspend 호출 시 응용 프로그램 hang 현상에 대한 덤프 분석
11474정성태3/27/201819450오류 유형: 459. xperf: error: TEST.Event: Invalid flags. (0x3ec).
11473정성태3/22/201824594.NET Framework: 734. C# - Thread.Suspend 호출 시 응용 프로그램 hang 현상파일 다운로드2
11472정성태3/22/201818568개발 환경 구성: 356. GTX 1070, GTX 960, GT 640M의 cudaGetDeviceProperties 출력 결과
11471정성태3/20/201821950VC++: 125. CUDA로 작성한 RGB2RGBA 성능 [1]파일 다운로드1
11470정성태3/20/201824124오류 유형: 458. Visual Studio - CUDA 프로젝트 빌드 시 오류 C1189, expression must have a constant value
11469정성태3/19/201817137오류 유형: 457. error MSB3103: Invalid Resx file. Could not load file or assembly 'System.Windows.Forms, ...' or one of its dependencies.
11468정성태3/19/201816670오류 유형: 456. 닷넷 응용 프로그램 실행 시 0x80131401 예외 발생
11467정성태3/19/201816084오류 유형: 455. Visual Studio Installer - 업데이트 실패
11466정성태3/18/201817234개발 환경 구성: 355. 한 대의 PC에서 2개 이상의 DirectX 게임을 실행하는 방법
11463정성태3/15/201819573.NET Framework: 733. 스레드 간의 read/write 시에도 lock이 필요 없는 경우파일 다운로드1
11462정성태3/14/201822442개발 환경 구성: 354. HTTPS 호출에 대한 TLS 설정 확인하는 방법 [1]
11461정성태3/13/201825068오류 유형: 454. 윈도우 업데이트 설치 오류 - 0x800705b4 [1]
11460정성태3/13/201817555디버깅 기술: 112. windbg - 닷넷 메모리 덤프에서 전역 객체의 내용을 조사하는 방법
11459정성태3/13/201818366오류 유형: 453. Debug Diagnostic Tool에서 mscordacwks.dll을 찾지 못하는 문제
11458정성태2/21/201819346오류 유형: 452. This share requires the obsolete SMB1 protocol, which is unsafe and could expose your system to attack. [1]
11457정성태2/17/201824069.NET Framework: 732. C# - Task.ContinueWith 설명 [1]파일 다운로드1
... 91  92  93  94  95  96  97  [98]  99  100  101  102  103  104  105  ...