16

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

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

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

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

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

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

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

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

在此处输入图像描述

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

更新1:

我上传了客户端服务器配置,也许这​​有帮助。

更新 2:

根据 Yahia 的建议,我们包含了ConnectionLimit (connection=80) 的配置参数。目前,这似乎解决了问题,但我们仍然尝试重现错误。

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

异常详情

4

5 回答 5

4

Ok, this is what happening - you have a faulty network card that is being overheated after few hours and when that happens it begins to short-circuit, as result your client side "thinks" that the server was shut down. End of story - 100% sure. where's my bounty?

btw: it is overheated either cause of bad design especially if you are using laptop or due to a damage already exists in it.

于 2013-04-04T14:32:38.583 回答
4

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

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

有一个注册表设置和一种编程方式- 您可能需要增加对客户端的限制(取决于您使用的线程数量)......

其他相关设置(客户端)可以在这里找到。

于 2013-03-21T14:45:31.783 回答
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++;
            }
于 2013-04-04T06:00:50.943 回答
2

我建议验证2点:

  1. 在服务器上进行节流,例如

    行为名称="Throttled"
    serviceThrottling
    maxConcurrentCalls="1"
    maxConcurrentSessions="1"
    maxConcurrentInstances="1"

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

几年前的事了,具体记不太清了。另外,我记得我找到了一篇很好的文章,描述了如何以及为什么要更改服务实例模式来帮助解决这个(会话)问题。

于 2013-03-28T21:17:05.843 回答
0

我有同样的问题。就我而言,这是我的错误。我在启动线程后关闭了 channelFactory(代理)。

于 2015-10-19T00:44:35.053 回答