0

我有一个从 WCF 托管站点 (IIS) 获取所有业务逻辑的 ASP.Net 网站。有时,后端 WCF 似乎冻结了,这使 Web 前端停止响应。我必须回收两个应用程序池才能使其再次工作。

  • 最近这种情况更频繁地发生,可能是因为我们有越来越多的客户使用该网站。以前每月一次,现在每周一次。也许更多。
  • 我们会在每次 SVC 调用后关闭连接。
  • 回收池后在事件日志中收到错误消息

消息:System.ServiceModel.CommunicationException:接收到....../......BusinessServices.svc 的 HTTP 响应时发生错误。这可能是由于服务端点绑定未使用 HTTP 协议。这也可能是由于服务器中止了 HTTP 请求上下文(可能是由于服务关闭)。有关更多详细信息,请参阅服务器日志。---> System.Net.WebException:底层连接已关闭:接收时发生意外错误。---> System.IO.IOException: Unable to read data from the transport connection: 一个现有的连接被远程主机强行关闭。---> System.Net.Sockets.SocketException: 现有连接被远程主机强行关闭

  • Web 应用程序的 Web.config:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IBusinessServices" closeTimeout="00:31:00" openTimeout="00:31:00"
receiveTimeout="00:10:00" sendTimeout="00:31:00"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
  <readerQuotas maxDepth="999" maxStringContentLength="2147483647" maxArrayLength="1638400"
  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
   <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" />
          </security>
   </binding>
        </wsHttpBinding>
      </bindings>
   <client>
    <endpoint address="http://localhost:8890/MyBusinessServices.svc" binding="wsHttpBinding"
 bindingConfiguration="WSHttpBinding_IBusinessServices"
contract="MyBusinessServices.IBusinessServices"
 name="WSHttpBinding_IBusinessServices" />
 </client>
  • WCF 服务的 Web.config,限制设置为 1500

    ......

        <behavior name="AppServiceBehaviors">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
          <serviceTimeouts transactionTimeout="00:15:00" />
          <serviceThrottling maxConcurrentCalls="1500" maxConcurrentSessions="1500"
            maxConcurrentInstances="2147483647" />
        </behavior>
    
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    

这个问题是间歇性的,但它让我发疯。任何想法/建议表示赞赏。

埃里克

4

2 回答 2

0

您现在面临的问题可能是由于许多其他因素造成的,这些因素需要比我们目前拥有的更多的描述。

抛出的异常是一种通用异常,可能指向许多可能的场景。例如,如果您的服务服务器前面有一个负载均衡器,其中一个在运行时出错,而另一个没有。另一个例子是 sql server 在服务器端创建了一个异常,但是您的包装异常可能不会将相关信息发送到您的客户端。所以你无法确切知道发生了什么。

我有一些建议供您检查:

我可以看到您已经表示您在每次通话后都将关闭连接。但是您需要确保收到异常的调用也被关闭。所以你的 svc 调用应该是这样的:

try
  {
     if (this.client != null)
     {
        IClientChannel channel = this.client as IClientChannel;
        if (channel.State == CommunicationState.Faulted)
        {
           channel.Abort();
        }
        else
        {
           channel.Close();
        }
     }
  }
  finally
  {
     this.client = null;
  }

除此之外,您可能还想检查 IIS 上的应用程序池设置。您可以从事件日志中确保您不会被迫使用最大故障设置进行回收/关闭。(在高级应用程序池设置中 - rapidFailProtectionMaxCrashes)

于 2013-05-21T11:57:04.067 回答
0

我给你的 2 美分,

服务中止 - 由于内部发生致命错误而导致的错误,

确保在 Dev 的 VS IDE 中调试 WCF 时,保留异常(Ctrl D,E),检查所有“未处理的异常”列。这使 IDE 能够准确地中断应用程序代码行,尽管 CATCHes ..这将挖掘任何错误。

如果这里有任何发现,请告诉我们...

祝你好运,HydTechie

于 2013-05-28T06:11:26.020 回答