Microsoft MVP성태의 닷넷 이야기
.NET Framework: 97. WCF : netTcpBinding에서의 각종 Timeout 값 설명 [링크 복사], [링크+제목 복사]
조회: 26697
글쓴 사람
정성태 (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분
@초보 직접 해보시고 그 결과를 덧글로 달아주신다면 더 좋지 않을까요? ^^
정성태

[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13600정성태4/18/2024271닷넷: 2242. C# - 관리 스레드와 비관리 스레드
13599정성태4/17/2024287닷넷: 2241. C# - WAV 파일의 PCM 사운드 재생(Windows Multimedia)파일 다운로드1
13598정성태4/16/2024312닷넷: 2240. C# - WAV 파일 포맷 + LIST 헤더파일 다운로드1
13597정성태4/15/2024378닷넷: 2239. C# - WAV 파일의 PCM 데이터 생성 및 출력파일 다운로드1
13596정성태4/14/2024753닷넷: 2238. C# - WAV 기본 파일 포맷파일 다운로드1
13595정성태4/13/2024874닷넷: 2237. C# - Audio 장치 열기 (Windows Multimedia, NAudio)파일 다운로드1
13594정성태4/12/20241007닷넷: 2236. C# - Audio 장치 열람 (Windows Multimedia, NAudio)파일 다운로드1
13593정성태4/8/20241050닷넷: 2235. MSBuild - AccelerateBuildsInVisualStudio 옵션
13592정성태4/2/20241206C/C++: 165. CLion으로 만든 Rust Win32 DLL을 C#과 연동
13591정성태4/2/20241167닷넷: 2234. C# - WPF 응용 프로그램에 Blazor App 통합파일 다운로드1
13590정성태3/31/20241072Linux: 70. Python - uwsgi 응용 프로그램이 k8s 환경에서 OOM 발생하는 문제
13589정성태3/29/20241142닷넷: 2233. C# - 프로세스 CPU 사용량을 나타내는 성능 카운터와 Win32 API파일 다운로드1
13588정성태3/28/20241195닷넷: 2232. C# - Unity + 닷넷 App(WinForms/WPF) 간의 Named Pipe 통신파일 다운로드1
13587정성태3/27/20241154오류 유형: 900. Windows Update 오류 - 8024402C, 80070643
13586정성태3/27/20241296Windows: 263. Windows - 복구 파티션(Recovery Partition) 용량을 늘리는 방법
13585정성태3/26/20241094Windows: 262. PerformanceCounter의 InstanceName에 pid를 추가한 "Process V2"
13584정성태3/26/20241047개발 환경 구성: 708. Unity3D - C# Windows Forms / WPF Application에 통합하는 방법파일 다운로드1
13583정성태3/25/20241156Windows: 261. CPU Utilization이 100% 넘는 경우를 성능 카운터로 확인하는 방법
13582정성태3/19/20241417Windows: 260. CPU 사용률을 나타내는 2가지 수치 - 사용량(Usage)과 활용률(Utilization)파일 다운로드1
13581정성태3/18/20241586개발 환경 구성: 707. 빌드한 Unity3D 프로그램을 C++ Windows Application에 통합하는 방법
13580정성태3/15/20241136닷넷: 2231. C# - ReceiveTimeout, SendTimeout이 적용되지 않는 Socket await 비동기 호출파일 다운로드1
13579정성태3/13/20241493오류 유형: 899. HTTP Error 500.32 - ANCM Failed to Load dll
13578정성태3/11/20241628닷넷: 2230. C# - 덮어쓰기 가능한 환형 큐 (Circular queue)파일 다운로드1
13577정성태3/9/20241874닷넷: 2229. C# - 닷넷을 위한 난독화 도구 소개 (예: ConfuserEx)
13576정성태3/8/20241543닷넷: 2228. .NET Profiler - IMetaDataEmit2::DefineMethodSpec 사용법
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...