客户端CommunicationException,而服务正常工作

时间:2013-03-15 10:27:43

标签: c# asp.net .net wcf exception

目前我正面临一个我不明白的问题。我有一个wcf客户端,它同时通过几个线程调用wcf服务(两者都在同一台机器上)。有时,我会遇到众所周知的System.ServiceModel.CommunicationException

“接收到xxx的HTTP响应时发生错误。这可能是由于服务端点绑定不使用HTTP协议。这也可能是由于HTTP请求上下文被服务器中止(可能是由于服务关闭)。有关详细信息,请参阅服务器日志。“

有时它有效。如果服务调用成功,它似乎是完全随机的。

请求非常小,只是一个(int,bool,enum)调用。该请求包含ca.来自MSSQL数据库的300-500 KB记录。

我在网站上搜索了数百个客户端和服务端的解决方案,增加了超时值,缓冲区值,请求和响应大小值。我添加了[DataContract]和[DataMember]属性,因为它们丢失了。而且仍然没有变化。

我激活了完整的跟踪,只是为了看到一个非常奇怪的行为:

来自客户端的调用在本地停止并带有给定的异常 - 但是服务器处理它们并发送一个永远不会到达客户端的响应。检查给定跟踪的时间 - 客户端中止,服务器继续。

在追踪中,我看到了这张图中的重量:

enter image description here

拜托,任何人都可以帮助阻止这种无休止的搜索吗?

更新1:

我上传了clientserver配置,也许这​​有帮助。

更新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:

Client Trace Server Trace

更新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:

Exception details

5 个答案:

答案 0 :(得分:4)

HTTP协议定义了同一个Web服务器的2个连接的限制...

由于您使用http,您看到的行为可能与该限制有关...

有一个registry settingprogramatic way - 您可能需要在客户端上增加该限制(取决于您使用的线程数量)...

可以找到其他相关设置(客户端)here

答案 1 :(得分:4)

好的,这就是发生的事情 - 你有一个故障的网卡在几个小时后过热,当发生这种情况时会开始短路,因此你的客户端“认为”服务器已关闭。故事结束 - 100%肯定。哪里是我的赏金?

顺便说一下:如果您使用的是笔记本电脑或者因为已经存在损坏,它会导致设计不良。

答案 2 :(得分:2)

我建议验证2分:

    服务器上的
  1. Throttling,例如

    行为名称=“受限制”
               serviceThrottling
                 maxConcurrentCalls =“1”
                 maxConcurrentSessions =“1”
                 maxConcurrentInstances = “1”

  2. 未关闭的WCF会话 - 使用后是否关闭所有会话(客户端代理)?
    在我的情况下,当我将所有超时扩大到最大值时,我在X调用之后得到了情况,服务变得“卡住”。当我改变超时时,我收到了与你不同的例外情况。

  3. 几年前,我完全不记得了。 另外,我记得我找到了一篇很好的文章,描述了如何以及为什么要更改服务实例模式以帮助解决此(会话)问题。

答案 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(代理)。