약 10번 정도 호출한 후 WCF가 응답을 중지합니다(제한).
-
09-09-2019 - |
문제
WCF 서비스와 이에 대한 서비스 참조가 포함된 응용 프로그램이 있고 응용 프로그램에 루프가 있으며 각 반복마다 이 wcf 웹 서비스의 메서드를 호출합니다.
문제는 9번 정도 통화하면 그냥 멈춘다는거고... Pause
VS 버튼을 누르면 전화를 걸던 회선에 멈춰 있는 것을 볼 수 있습니다.
한참을 기다린 끝에 이건 시간 초과 예외 던져진다 :
요청 채널이 시간 초과되었습니다. 이후 답장을 기다리는 중 00:00:59.9970000.시간 제한 늘리기 Request 또는 에서 SendTimeout 값을 늘립니다. 제본.여기에 할당된 시간 operation은 의 일부였을 수 있습니다. 시간 초과가 더 깁니다.
이에 대해 조금 조사한 결과 애플리케이션에서 app.config를 편집하는 것과 관련된 몇 가지 솔루션을 찾았으며 여기에 그 내용이 발췌되어 있습니다.
<serviceBehaviors>
<behavior name="ThrottlingIssue">
<serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
</behavior>
</serviceBehaviors>
.
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
그런 다음 디버깅을 중지한 후 몇 분 후에 다음과 같은 오류 메시지가 나타납니다. 치명적인 실패 발생했습니다.
이 문제를 어떻게 해결할 수 있나요?일반 웹 서비스로 작업할 때는 이 문제가 발생하지 않았습니다.
참고로 전체 내용은 이렇습니다 app.config
:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ThrottlingIssue">
<serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDBInteractionGateway" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:28918/DBInteractionGateway.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDBInteractionGateway"
contract="DBInteraction.IDBInteractionGateway" name="WSHttpBinding_IDBInteractionGateway">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
[업데이트] 해결책:
보기에, 각 요청 후에는 다음을 수행해야 합니다. Close
연결...이제 각 요청 후에 연결을 닫고 있는데 매력적으로 작동하고 있습니다.
아직도 이해할 수 없는 점은 내 app.config에서 maxConcurrentCalls 및 maxConcurrentSessions를 500으로 설정했지만 아직 10개만 만들 수 있다는 것입니다.이에 대한 답을 갖고 있는 사람이 있나요?(어쩌면 위에 게시된 내 app.config에 문제가 있을 수 있습니다)
위 질문(현재 점선)에 대한 대답은 클라이언트를 편집하고 있었기 때문입니다. app.config
, 서비스 구성 파일이 아님(web.config
)
해결책
허용 된 동시 연결의 기본 번호는 10입니다.
클라이언트가 연결을 닫지 않을 가능성이 높습니다.
동시 통화 수를 늘리려면 클라이언트가 아닌 서비스 구성에 동작을 추가해야합니다.
다른 팁
clientservice.close ()로 전화하면 문제가 해결됩니다.
이번 주에 이 문제에 부딪혔는데 무슨 일이 일어나고 있는지 잘 알 수 없었습니다.실제로 내 서비스에 대한 호출을 다음으로 변경했습니다. Dispose()
서비스 클라이언트에 연결했지만 아무런 효과가 없는 것 같습니다.분명히 어딘가에 또 다른 서비스 호출이 숨어 있었던 것 같습니다.
주목할 만한 흥미로운 점은 내가 이것이 다음과 같은 결정을 내리게 만들었다는 것입니다. ~ 아니다 문제:이 제한은 웹 서비스에 대한 실제 소켓 연결 수와 관련이 없습니다.당신이 쳤을 때 maxConcurrentSessions
한계, 아직밖에 없어 하나의 실제 소켓 연결.이걸로 확인하고 있었어 netstat
, 이로 인해 잘못된 결론이 나왔습니다.그래서, 세션과 소켓을 혼동하지 마십시오.
모든 WCF 서비스에 대해 인터페이스가 정의되어 있으므로 이제 코드에서 이 패턴을 적용할 계획입니다.
IMyService service = new MyServiceClient();
using (service as IDisposable)
{
service.MyServiceMethod();
}
또한 흥미로운 점은 서비스(및 웹 사이트)가 IIS에서 호스팅될 때 문제가 발생하지 않았다는 것입니다.구성은 (거의) 동일하지만 해당 컴퓨터에서 이 동작을 재현할 수 없습니다.좋은 일인 것 같아요 :)
@ John Saunders(변수 할당에 대해 using
):
나는 보통 변수 할당을 using
성명.그러나 생성된 IMyService는 암시적으로 다음으로 변환될 수 없습니다. IDisposable
.정말로 그 과제를 원했다면 대안은 다음과 같을 것입니다.
IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}
그래도 여전히 변수 범위 문제가 잘못되었습니다.에 대한 참조 IService service
사용할 수 없지만 여전히 범위 내에 있습니다.그런 점에서는 이것이 더 나을 것입니다.
using (IDisposable serviceDisposable = new ServiceClient())
{
IService service = (IService)serviceDisposable;
}
하지만 추가 변수 이름을 도입해야 합니다. *으악*
웹 서비스 참조와 응용 프로그램 사이의 인터페이스로서 싱글 톤 클래스를 만들어 해결할 수 있습니다. 그런 다음 서비스 참조 인스턴스 만 만듭니다.
class ServiceInterface
{
private static ServiceInterface _instance;
private ServiceClient _service = new ServiceClient ;
private ServiceInterface()
{
//Prevent accessing default constructor
}
public static ServiceInterface GetInstance()
{
if(_instance == null)
{
_instance = new ServiceInterface();
}
return _instance;
}
// You can add your functions to access web service here
Public int PerformTask()
{
return _service.PerformTask();
}
}
할 수 있나요 추적을 구성합니다 그리고 루프를 실행 하시겠습니까? 채널이 결함이 생겨 클라이언트가 시간을 초래할 수 있습니다.
내 머리카락을 a 많이 어느 쪽이도 해결되지 않은 비슷한 문제 Close()
또는 Dispose()
나는 하루를 보낸 간단한 솔루션을 추가하고 싶습니다. ServicePointManager.DefaultConnectionLimit
기본적으로 2입니다.
"DefaultConnectionLimit 속성은 ServicePointManager 개체가 ServicePoint 개체를 작성할 때 ConnectionLimit 속성에 할당하는 기본 최대 동시 연결 수를 설정합니다."
제 경우에는 내 응용 프로그램이 원격 서비스에 2 번 성공적으로 연결되었으며 세 번째 시도에서는 단순히 서비스에 연결하려고 시도하지 않았습니다. 대신 위의 질문에서와 동일한 오류 메시지로 시간을 내기 전에 잠시 기다렸다. 증가 DefaultConnectionLimit
이것을 해결했습니다. 좌절감을 더하기 위해이 동작은 다소 무작위였습니다. 10의 경우 웹 서비스는 여러 번 (> 2) 여러 번 성공적으로 호출되었습니다.
솔루션은이 두 스레드에서 시작되고 추가로 논의됩니다. WCF- 타임 아웃-예고-검증 된 조사 그리고 WCF 서비스 스로틀. 내 문제를 해결했습니다.