目前我正面临一个我不明白的问题。我有一个wcf客户端,它同时通过几个线程调用wcf服务(两者都在同一台机器上)。有时,我会遇到众所周知的System.ServiceModel.CommunicationException
“接收到xxx的HTTP响应时发生错误。这可能是由于服务端点绑定不使用HTTP协议。这也可能是由于HTTP请求上下文被服务器中止(可能是由于服务关闭)。有关详细信息,请参阅服务器日志。“ ,
有时它有效。如果服务调用成功,它似乎是完全随机的。
请求非常小,只是一个(int,bool,enum)调用。该请求包含ca.来自MSSQL数据库的300-500 KB记录。
我在网站上搜索了数百个客户端和服务端的解决方案,增加了超时值,缓冲区值,请求和响应大小值。我添加了[DataContract]和[DataMember]属性,因为它们丢失了。而且仍然没有变化。
我激活了完整的跟踪,只是为了看到一个非常奇怪的行为:
来自客户端的调用在本地停止并带有给定的异常 - 但是服务器处理它们并发送一个永远不会到达客户端的响应。检查给定跟踪的时间 - 客户端中止,服务器继续。
在追踪中,我看到了这张图中的重量:
拜托,任何人都可以帮助阻止这种无休止的搜索吗?
更新1:
更新2:
根据Yahia的建议,我们为ConnectionLimit(connection = 80)添加了config parameter。目前,似乎这解决了问题,但我们仍然试图重现错误。
更新3:
该死。三个小时后,我再次看到相同的行为......我们有另一个建议:正如你所看到的,我们在客户端使用quartz.net,从20个线程开始。石英发动机执行的工作连接到我们的服务。现在我试着想象如果7个线程试图同时连接服务会发生什么。
更新4:
我们在注册表和配置中设置了tcp参数。重启后,没有任何变化:(
这些是注册表更改:
HKLM \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters - TcpNumConnections = 65534
HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters - MaxUserPort = 65534
HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Internet Settings - MaxConnectionsPer1_0Server = 20
HKLM \ Software \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTIONSPERSERVER - iexplore.exe = 20
HKLM \ Software \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTIONSPERSERVER - MyClientsExeName.exe = 20
更新5:
更新6:
[DataContract]
public class Currency
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Code { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public ForeignNoteDetails ForeignNoteDetails { get; set; }
[DataMember]
public CurrencyRates Rates { get; set; }
[DataMember]
public PreciousMetallDetails PreciousMetallDetails { get; set; }
[DataMember]
public CurrencyType Type { get; set; }
}
[DataContract]
public class ForeignNoteDetails
{
[DataMember]
public double CardholderBillingCurrencyCode { get; set; }
[DataMember]
public string Country { get; set; }
[DataMember]
public string CountryCode { get; set; }
[DataMember]
public int CurrencyUnit { get; set; }
[DataMember]
public List<string> Notes { get; set; }
}
[DataContract]
public class CurrencyRates
{
[DataMember]
public ExchangeRate PurchaseRate { get; set; }
[DataMember]
public ExchangeRate SellRate { get; set; }
}
[DataContract]
public class PreciousMetallDetails
{
[DataMember]
public string PreciousMetalType { get; set; }
[DataMember]
public double Fineness { get; set; }
}
致电服务:
protected IEnumerable<Currency> GetCurrencyLevel(int id, bool netRate = true, RatesCalculationSource ratesSource = RatesCalculationSource.ReutersRates)
{
return this.calculationClient.GetCurrencyLevel(new RatesCalculationSetting() { CalculationLevelId = id, CalculateGrossRates = !netRate, Soruce = ratesSource });
}
创建客户:
protected ICalculationServiceClientService calculationClient = IoC.DependencyManager.Resolve<ICalculationServiceClientService>();
对服务的另一个调用(工作):
this.calculationClient.DistributeTradingOfficeRatesLevels(branchOfficeLevelId, tradingLevelId);
这被定义为
void DistributeTradingOfficeRatesLevels(int branchOfficeRatesLevelId, int tradingOfficeRatesLevelId)
更新7:
答案 0 :(得分:4)
HTTP协议定义了同一个Web服务器的2个连接的限制...
由于您使用http,您看到的行为可能与该限制有关...
有一个registry setting和programatic way - 您可能需要在客户端上增加该限制(取决于您使用的线程数量)...
可以找到其他相关设置(客户端)here。
答案 1 :(得分:4)
好的,这就是发生的事情 - 你有一个故障的网卡在几个小时后过热,当发生这种情况时会开始短路,因此你的客户端“认为”服务器已关闭。故事结束 - 100%肯定。哪里是我的赏金?
顺便说一下:如果您使用的是笔记本电脑或者因为已经存在损坏,它会导致设计不良。答案 2 :(得分:2)
我建议验证2分:
Throttling,例如
行为名称=“受限制”
serviceThrottling
maxConcurrentCalls =“1”
maxConcurrentSessions =“1”
maxConcurrentInstances = “1”
未关闭的WCF会话 - 使用后是否关闭所有会话(客户端代理)?
在我的情况下,当我将所有超时扩大到最大值时,我在X调用之后得到了情况,服务变得“卡住”。当我改变超时时,我收到了与你不同的例外情况。
几年前,我完全不记得了。 另外,我记得我找到了一篇很好的文章,描述了如何以及为什么要更改服务实例模式以帮助解决此(会话)问题。
答案 3 :(得分:2)
尝试在WCF端启用跟踪,您将获得有关服务器端发生情况的详细信息。
当客户端发送大量请求时,有时WCF通道工厂也会突然关闭。我们在使用WCF进行证书身份验证时遇到了类似的问题。因为我们围绕这个瞬态错误设计了RetryPolicy。如果我们收到此错误,我们将中止通道工厂,重新创建并再次发送,而不是抛出异常。
while (retryCount <= MAXRETRY)
{
try
{
return _proxyService.GetData(); // _proxyService is WCF proxy class
}
catch (CommunicationException transientException)
{
if (SLEEPINTERVAL> 0)
{
Thread.Sleep(SLEEPINTERVAL);
}
((IClientChannel) _proxyService).Abort();
_proxyService = functionToCreateProxy();
}
retryCount++;
}
答案 4 :(得分:0)
我遇到了同样的问题。在我的情况下,这是我的错误。我在启动线程后关闭了channelFactory(代理)。