[wcf] WCF 제한 시간 예외 세부 조사

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 라이브러리를 다시 보도록 강요했습니다.



답변

.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>


답변

아직 시도하지 않은 경우 서버 측 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가 실제로 응답을 다시 보내는 지 확인할 수 있습니다.


답변

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

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


답변

나는 매우 비슷한 문제가 있습니다. 과거에는 이것은 직렬화 문제와 관련이있었습니다. 이 문제가 계속 발생하는 경우 반환하는 개체를 올바르게 직렬화 할 수 있는지 확인할 수 있습니다. 특히 관계가있는 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에서 결과를 검사 할 수 있습니다.


답변

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


답변

방금 문제를 해결했는데 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”이면 오류가 발생합니다.


답변

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