WCF 제한 시간 예외 세부 조사


94

IIS7에서 실행되는 WCF 서비스 (* .svc)와 서비스를 쿼리하는 다양한 클라이언트가있는 응용 프로그램이 있습니다. 서버가 Win 2008 Server를 실행 중입니다. 클라이언트는 Windows 2008 Server 또는 Windows 2003 서버를 실행하고 있습니다. 실제로 많은 잠재적 WCF 문제와 관련이있을 수있는 다음 예외가 발생합니다.

System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. 

시간 제한을 30 분으로 늘 렸는데 오류가 계속 발생했습니다. 데이터의 양이 업로드 또는 다운로드하는 데 30 분이 걸리지 않기 때문에 다른 작업이 진행 중임을 알 수 있습니다.

오류가 발생했다가 사라집니다. 현재는 더 자주 발생합니다. 동시에 3 개의 클라이언트를 실행하거나 100 개를 실행해도 문제가되지 않는 것 같습니다. 여전히 가끔씩 발생합니다. 대부분의 경우 시간 제한이 없지만 여전히 시간당 몇 개를받습니다. 호출 된 모든 메서드에서 오류가 발생합니다. 이러한 메서드 중 하나에는 매개 변수가 없으며 약간의 데이터를 반환합니다. 다른 하나는 많은 데이터를 매개 변수로 사용하지만 비동기 적으로 실행합니다. 오류는 항상 클라이언트에서 발생하며 스택 추적에서 서버의 코드를 참조하지 않습니다. 항상 다음으로 끝납니다.

 at System.Net.HttpWebRequest.GetResponse()
  at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

서버에서 : 다음 바인딩 설정을 시도했으며 현재 가지고 있습니다.

maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"

영향이없는 것 같습니다.

나는 다음 제한 설정을 시도했으며 현재 가지고 있습니다.

<serviceThrottling maxConcurrentCalls="1500"   maxConcurrentInstances="1500"    maxConcurrentSessions="1500"/>

영향이없는 것 같습니다.

현재 WCF 서비스에 대해 다음 설정이 있습니다.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]

나는 ConcurrencyMode.Multiple잠시 동안 달렸 지만 여전히 오류가 발생했습니다.

IIS 다시 시작, 기본 SQL Server 다시 시작, 컴퓨터 다시 시작을 시도했습니다. 이 모든 것이 영향을 미치지 않는 것 같습니다.

Windows 방화벽을 비활성화 해 보았습니다. 영향이없는 것 같습니다.

클라이언트에는 다음 설정이 있습니다.

maxReceivedMessageSize="2147483647"

<system.net>
    <connectionManagement>
    <add address="*" maxconnection="16"/>
</connectionManagement> 
</system.net>

내 클라이언트가 연결을 닫습니다.

var client = new MyClient();

try
{
    return client.GetConfigurationOptions();
}
finally
{
    client.Close();
}

더 많은 나가는 연결을 허용하도록 레지스트리 설정을 변경했습니다.

MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.

나는 최근에 SvcTraceViewer.exe를 시도했습니다. 클라이언트 측에서 한 가지 예외를 포착했습니다. 시간이 1 분임을 알 수 있습니다. 서버 측 추적을 보면 서버가이 예외를 인식하지 못하는 것을 알 수 있습니다. 내가 볼 수있는 최대 시간은 10 초입니다.

exec sp_who서버에서 사용 하는 활성 데이터베이스 연결을 살펴 보았습니다 . 나는 몇 개 밖에 없다 (2-3). TCPview를 사용하여 한 클라이언트의 TCP 연결을 살펴 보았습니다. 보통 2-3 개 정도이고 5 개 또는 6 개까지 봤습니다.

간단히 말해서 나는 당황합니다. 나는 내가 찾을 수있는 모든 것을 시도했고, WCF 전문가가 볼 수있는 매우 간단한 것을 놓치고있을 것입니다. 서버가 실제로 메시지를 수신하기 전 및 / 또는 서버 수준에서 메시지를 대기열에 추가하고 처리하지 못하게하는 것이 저수준 (TCP)에서 클라이언트를 차단하는 것이 내 직감입니다.

봐야 할 성능 카운터가 있으면 알려주세요. (이 카운터 중 일부는 해독하기 어렵 기 때문에 어떤 값이 나쁜지 표시하십시오). 또한 WCF 메시지 크기를 어떻게 기록 할 수 있습니까? 마지막으로 클라이언트와 서버 사이에 몇 개의 연결을 설정할 수 있는지 테스트 할 수있는 도구가 있습니까 (내 응용 프로그램과 독립적으로)

시간 내 줘서 고마워!

6 월 20 일에 추가 된 추가 정보 :

내 WCF 응용 프로그램은 다음과 유사한 작업을 수행합니다.

while (true)
{
   Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
   Step2GetWorkUnitFromServerViaWCF();
   DoWorkLocally(); // takes 5-15minutes. 
   Step3SendBackResultsToServerViaWCF();
}

WireShark를 사용하여 오류가 발생하면 5 번의 TCP 재전송이 있고 나중에 TCP가 재설정된다는 것을 알았습니다. 내 생각 엔 RST는 WCF에서 연결을 끊는 것입니다. 내가 얻는 예외 보고서는 Step3 시간 초과입니다.

저는 tcp 스트림 "tcp.stream eq 192"를보고 이것을 발견했습니다. 그런 다음 필터를 "tcp.stream eq 192 및 http 및 http.request.method eq POST"로 확장하고이 스트림 동안 6 개의 POST를 확인했습니다. 이상하게 보였기 때문에 tcp.stream eq 100과 같은 다른 스트림으로 확인했습니다. POST가 세 번 있었는데, 세 번의 호출을하고 있기 때문에 좀 더 정상적인 것 같습니다. 그러나 모든 WCF 호출 후에 연결을 끊기 때문에 스트림 당 하나의 호출을 예상했을 것입니다 (하지만 TCP에 대해서는 잘 모릅니다).

좀 더 조사하면서 http 패킷로드를 디스크에 덤프하여이 6 개의 호출이 어디에 있는지 살펴 보았습니다.

1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2

내 생각에 두 명의 동시 클라이언트가 동일한 연결을 사용하고 있으므로 중복을 본 것입니다. 그러나 여전히 이해할 수없는 몇 가지 문제가 더 있습니다.

a) 패킷이 손상된 이유는 무엇입니까? 랜덤 네트워크 플루크-어쩌면? 로드는 다음 샘플 코드를 사용하여 gzip으로 압축됩니다. http://msdn.microsoft.com/en-us/library/ms751458.aspx- 코드를 동시에 사용할 때 가끔 버그가 발생할 수 있습니까? gzip 라이브러리없이 테스트해야합니다.

b) 손상된 작업이 시간 초과 된 후 1 단계와 2 단계가 실행되는 이유는 무엇입니까? 이러한 작업이 발생하지 않아야하는 것처럼 보입니다. TCP에 대한 이해가 결함이 있기 때문에 올바른 스트림을보고 있지 않을 수 있습니다. 동시에 발생하는 다른 스트림이 있습니다. 다른 스트림을 조사해야합니다. 스트림 190-194를 살펴보면 Step3 POST에 적절한 페이로드 데이터 (손상되지 않음)가 있음을 알 수 있습니다. gzip 라이브러리를 다시 보도록 강요했습니다.


Jason-이 문제를 해결 했습니까? DefaultConnectionLimit 설정 이었습니까?
SFun28

2
@JasonKealey-다른 많은 질문과는 달리, 질문을 게시하기 전에 자신을 위해 노력하지 않는다는 비난을받을 수 없습니다. :) 질문이 너무 상세하고 모든 중요한 세부 사항을 포함하고 있다는 점이 마음에 듭니다. 내가 솔루션뿐만 아니라 :) 같은 희망 때문에 증상은 당신이 아주 많이 내 같은 외모를 설명
Øyvind Bråthen

답변:


51

.Net 클라이언트를 사용하는 경우 설정하지 않았을 수 있습니다.

//This says how many outgoing connection you can make to a single endpoint. Default Value is 2
System.Net.ServicePointManager.DefaultConnectionLimit = 200;

다음은 원래 질문과 답변입니다. WCF Service Throttling

업데이트 :

이 구성은 .Net 클라이언트 응용 프로그램에 들어갑니다. 시작할 때 또는 테스트를 시작하기 전에있을 수 있습니다.

또한 app.config 파일에서 다음과 같이 가질 수 있습니다.

<system.net>
    <connectionManagement>
      <add maxconnection = "200" address ="*" />
    </connectionManagement>
  </system.net>

이것은 유망 해 보입니다. 다음 확장 성 테스트 중에 테스트하기 위해 이것을 포함했습니다. 충돌을 일으키는 임의의 설정과 똑같아 보입니다. :) 포인터 주셔서 감사합니다.
Jason Kealey 2010

1
@Jason : 서버 프로그래머라면 서버의 확장 성을 유지하는 것이 얼마나 중요한지, 그리고 위에서 사용한 후에도 현재 동시성 문제를 겪고있는 사람도 알고 있습니다. 다음 질문을 살펴볼 수 있다면 stackoverflow.com/questions/2637175/wcf-network-cost 클라이언트와 서버 간의 지연 시간이 31ms이며이를 줄여야합니다.
Mubashar

3
1 년 밖에 걸리지 않았지만 마침내이 플래그가 설정된 애플리케이션에서 또 다른 스트레스 테스트를 실행했습니다. 문제가 해결 된 것으로 보이므로 최선의 답변을드립니다. 이것이 필요한 퍼즐의 마지막 조각이지만 오류가 발생하지 않도록 다른 모든 요소가 제자리에 있어야한다는 사실에 놀라지 않을 것입니다. 매우 감사합니다!
Jason Kealey 2011

2
@Aris : .net 클라이언트 응용 프로그램에서 시작시 또는 전역 구성을 설정 한 위치에서 구성 가능하게 유지하려면 다음과 같이 구성 파일에 추가 할 수 있습니다. <system.net> <connectionManagement> <add maxconnection = "200"주소 = "*"/> </ connectionManagement> </system.net>
Mubashar

3

아직 시도하지 않은 경우 서버 측 WCF 작업을 try / finally 블록에 캡슐화하고 실제로 반환되는지 확인하기 위해 로깅을 추가합니다.

작업이 완료되었음을 표시하는 경우 다음 단계는 더 낮은 수준으로 이동하여 실제 전송 계층을 살펴 보는 것입니다.

Wireshark 또는 다른 유사한 패킷 캡처 도구는이 시점에서 매우 유용 할 수 있습니다. 이것이 표준 포트 80에서 HTTP를 통해 실행되고 있다고 가정합니다.

클라이언트에서 Wireshark를 실행합니다. 캡처를 시작할 때 옵션에서 캡처 필터를 다음으로 설정합니다 tcp http and host service.example.com . 이는 관련없는 트래픽의 양을 줄입니다.

가능하면 정확한 통화 시작 시간과 시간 초과가 발생한 시간을 알리도록 클라이언트를 수정하십시오. 또는 면밀히 모니터링하십시오.

오류가 발생하면 Wireshark 로그를 검색하여 통화 시작을 찾을 수 있습니다. 클라이언트가 호출하는 첫 번째 패킷 (GET /service.svc 또는 POST /service.svc와 유사해야 함)을 마우스 오른쪽 단추로 클릭하고 TCP 스트림 팔로우를 선택하십시오.

Wireshark는 전체 HTTP 대화를 디코딩하므로 WCF가 실제로 응답을 다시 보내는 지 확인할 수 있습니다.


서버에 로그인했습니다. 그쪽에는 오류가 없습니다. 내가 무엇을 찾을 수 있는지 확인하기 위해 지금 WireShark를 실행하고 있습니다. 트래픽 양이 많기 때문에 분석하기가 어려울 수 있지만 발견 할 수 있으면 다시보고하겠습니다.
Jason Kealey 2009-06-18

지난 6 시간 동안 WireShark를 실행하고 약 60k 프레임을 수집했습니다. 오늘이 고객은 단 하나의 예외를보고했습니다. 분명히 오류 이메일을 보낸 후 RST (재설정)로 표시된 TCP 연결을 보았습니다. 아마도 연결을 종료하는 WCF 일 것입니다. 페이로드 (525k)를 디스크에 저장했습니다. 비슷한 크기의 페이로드를 가진 87 개의 다른 호출이 있음을 확인했습니다. 몇 번의 TCP 재전송을 보았지만 다른 호출에서도 일부를 보았습니다 (실패하지 않았습니다). 내 네트워킹 하드웨어 + 케이블에 대해 궁금해하기 시작했습니다.
Jason Kealey

로컬 네트워크에서도 TCP 재전송의 존재가 반드시 나쁜 것은 아닙니다. 두 개의 끝점을 단일 스위치에 물리적으로 연결할 수 있다면 한 번 시도해 볼 가치가 있을지 모르지만 그것이 고쳐질 것이라는 희망을 내놓지는 않을 것입니다. 가능하다면-약간의 트래픽을 서버로주고받는 매우 기본적인 클라이언트 응용 프로그램을 만드십시오. 이렇게하면 시간 초과를 유발할 수있는 애플리케이션 문제를 제거하는 데 도움이 될 수 있습니다.

또한 TCP 재설정 패킷을보고 있다고 언급했습니다. 그 시점에서 서버가 어떤 종류의 응답을 전달 했습니까 (또는 더 많은 데이터를 기다리고 있었습니까)? RST와 이전 패킷 사이에 상당한 지연이 있었습니까?

서버가 원격입니다. 도움이되는지 확인하기 위해 로컬에서 테스트 환경을 만들 계획입니다. RST는 5 번의 TCP 재전송 중 마지막 34 초 후에 전송되었습니다. (재전송 간격 1 ~ 8 초). 단서가 있습니까?
Jason Kealey 2009-06-20

2

출처 : http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx

이 시간 초과 오류를 방지하려면 WCF 클라이언트 코드에서 Proxy에 대한 OperationTimeout 속성 을 구성 해야 합니다. 이 구성은이 기사의 앞부분에서 논의한 Send Timeout, Receive Timeout 등과 같은 다른 구성과 달리 새로운 것입니다. 이 작업 시간 제한 속성 구성을 설정하려면 작업 계약 메서드를 호출하기 전에 프록시를 WCF 클라이언트 응용 프로그램의 IContextChannel로 캐스팅해야합니다.


나는 이것을 시도했다. 내가 넣은 시간 제한에 관계없이 여전히 시간이 초과되지만 작업이 그렇게 길지 않고 동일한 쿼리를 수행하는 다른 모든 클라이언트가이 시간 동안 작동하기 때문에 이것은 의미가 없습니다.
Jason Kealey 2009-06-11

내 테스트에 따르면 OperationTimeout은 단순히 구성에서 ReceiveTimeout을 재정의합니다. 따라서 아무 소용이 없습니다.
dudeNumber4

2

나는 매우 비슷한 문제가 있습니다. 과거에는 이것은 직렬화 문제와 관련이있었습니다. 이 문제가 계속 발생하는 경우 반환하는 개체를 올바르게 직렬화 할 수 있는지 확인할 수 있습니다. 특히 관계가있는 Linq-To-Sql 개체를 사용하는 경우 자식 개체에 대한 역 참조를 부모 개체에 배치하고 해당 역 참조를 DataMember로 표시하면 알려진 직렬화 문제가 있습니다.

서버 측에서 DataContractSerializer 및 클라이언트가 사용하는 모든 직렬화 방법을 사용하여 개체를 직렬화 및 역 직렬화하는 콘솔 앱을 작성하여 직렬화를 확인할 수 있습니다. 예를 들어 현재 애플리케이션에는 WPF 및 Compact Framework 클라이언트가 모두 있습니다. DataContractSerializer를 사용하여 직렬화하고 XmlDesserializer를 사용하여 역 직렬화 할 수 있는지 확인하기 위해 콘솔 앱을 작성했습니다. 당신은 그것을 시도 할 수 있습니다.

또한 자식 컬렉션이있는 Linq-To-Sql 개체를 반환하는 경우 서버 측에서 열심히로드했는지 확인할 수 있습니다. 지연로드로 인해 반환되는 개체가 채워지지 않고 요청이 서비스 메서드로 여러 번 전송되는 위치에서 표시되는 동작이 발생할 수 있습니다.

이 문제를 해결했다면 저도 그 문제에 얽매여 있기 때문에 어떻게하는지 듣고 싶습니다. 내 문제가 직렬화가 아님을 확인했기 때문에 손실이 발생했습니다.

업데이트 : 그것이 당신에게 도움이 될지 확실하지 않지만 Service Trace Viewer Tool은 당신과 매우 유사한 경험을 5 일 만에 내 문제를 해결했습니다. 추적을 설정 한 다음 원시 XML을 확인하여 직렬화 문제를 일으키는 예외를 발견했습니다. 이는 성공적으로 직렬화 할 수있는 것보다 더 많은 자식 개체를 가끔 가지고있는 Linq-to-SQL 개체와 관련이 있습니다. web.config 파일에 다음을 추가하면 추적이 활성화됩니다.

<sharedListeners>
    <add name="sharedListener"
         type="System.Diagnostics.XmlWriterTraceListener"
         initializeData="c:\Temp\servicetrace.svclog" />
  </sharedListeners>
  <sources>
    <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >
      <listeners>
        <add name="sharedListener" />
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
      <listeners>
        <add name="sharedListener" />
      </listeners>
    </source>
  </sources>

결과 파일은 Service Trace Viewer Tool을 사용하여 열거 나 IE에서 결과를 검사 할 수 있습니다.


2

요청 사이에 WCF 서비스에 대한 연결을 닫습니까? 그렇지 않으면이 정확한 시간 제한이 표시됩니다 (결국).


2

방금 문제를 해결했는데 App.config 파일의 노드가 잘못 구성되었음을 발견했습니다.

<client>
<endpoint name="WCF_QtrwiseSalesService" binding="wsHttpBinding" bindingConfiguration="ws" address="http://cntgbs1131:9005/MyService/TGE.ISupplierClientManager" contract="*">
</endpoint>
</client>

<bindings>
    <wsHttpBinding>
        <binding name="ws" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text">
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            <**security mode="None">**
                <transport clientCredentialType="None"></transport>
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

노드에서 구성을 확인하십시오 <security>. 속성 "mode"값은 "None"입니다. 값이 "Transport"이면 오류가 발생합니다.


보안에 영향을주지 않습니까? 이 대부분의 실제 애플리케이션을위한 해결책이 될 수 없습니다 그렇다면
Veverke

0

SOAP 툴킷 등을 사용 하여 clientVia 를 사용하여 전송 된 메시지를 보셨습니까 ? 이는 오류가 클라이언트 자체에서 발생하는지 또는 다른 곳에서 발생하는지 확인하는 데 도움이 될 수 있습니다.


WCF 호출에서이 정보를 더 쉽게 기록 할 수있는 사용되지 않는 SOAP 도구 키트보다 최신 도구를 알고 있습니까?
Jason Kealey 2009-06-15

SOAP Toolkitdeprecated
Kiquenet 2015

0

WCF 추적을 확인 했습니까? WCF는 예외를 삼키고 마지막 예외 만 반환하는 경향이 있습니다.이 예외는 끝 점이 의미있는 항목을 반환하지 않았기 때문에 발생하는 시간 제한입니다.


SvcTraceViewer를 시도했지만보고 된 유일한 예외는 시간 초과 (클라이언트에서)였습니다. 서버에보고 된 것이 없습니다.
Jason Kealey

추적에서 모든 옵션을 엽니 다. 모든 추적 옵션이 열려 있지 않을 수 있습니다. 또한 이벤트 추적 및 메시지 추적 파일을 모두 확인하십시오.
Miki Watts

0

기본적으로 설정되지 않은 enum 유형의 속성이 포함 된 개체를 클라이언트로 다시 전달하고 해당 enum에 0으로 매핑되는 값이없는 경우에도이 오류가 발생합니다. enum MyEnum{ a=1, b=2};


0

이 예외 메시지는 매우 일반적이며 다양한 이유로 인해 수신 될 수 있습니다. Windows 8.1 컴퓨터에 클라이언트를 배포하는 동안이 문제가 발생했습니다. WCF 클라이언트는 Windows 서비스 내부에서 실행되며 WCF 서비스를 지속적으로 폴링합니다. Windows 서비스는 관리자가 아닌 사용자로 실행됩니다. 이 문제는 WCF 구성에서 clientCredentialType을 "Windows"로 설정하여 다음과 같이 인증이 통과 할 수 있도록함으로써 해결되었습니다.

      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>

0

저는 WCF 전문가는 아니지만 IIS에서 DDOS 보호를 실행하고 있지 않은지 궁금합니다. 경험상 단일 클라이언트에서 서버로의 동시 연결을 실행하면 DDOS 공격을 의심하기 때문에 서버가 호출에 응답하지 않는다는 것을 경험으로 알고 있습니다. 또한 클라이언트의 공격 속도를 늦추기 위해 시간이 초과 될 때까지 연결을 열어 둡니다.

그러나 다른 컴퓨터 / IP에서 오는 다중 연결은 문제가되지 않습니다.

이 MSDN 게시물에 더 많은 정보가 있습니다.

http://msdn.microsoft.com/en-us/library/bb463275.aspx

MaxConcurrentSession 속성을 확인하십시오.


내가 본 모든 것에서 이것이 일어나고 있다고 생각하지만 (서버에서) : <serviceThrottling maxConcurrentCalls = "150"maxConcurrentInstances = "150"maxConcurrentSessions = "150"/> <serviceDebug includeExceptionDetailInFaults = "true" /> 이것이 발생하는지 확인하기 위해 모니터링 할 수있는 성능 모니터 또는 IIS 로그가 있습니까?
Jason Kealey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.