【问题标题】:WCF Response Message Takes 40 Minutes and No Timeout Exception is ThrownWCF 响应消息需要 40 分钟并且没有引发超时异常
【发布时间】:2010-11-15 12:27:15
【问题描述】:

我有一个托管在 IIS7 中的 WCF 服务(服务和客户端配置在本文末尾)。我遇到了一个奇怪的场景,我希望有人可能对如何攻击它并找到解决方案有一些想法。

该服务仅公开一个合同,“ProcessMessage”。我可以使用该合约发送/接收来自服务的同步消息,性能良好,但对该合约的一次特定调用会返回超过 65KB 的数据;大约 1 MB。在最初调用它时,我收到了预期的最大接收大小超出错误。所以我增加了 maxReceivedMessageSize,现在这个特殊的调用需要 40 分钟才能返回到客户端。这远远超出了任何超时设置,也远远超出了我的预期。服务器端处理时间仅为 2 秒。它似乎被客户端搁置了。

我还尝试提高文件中的其他几个配额,但无济于事。

任何想法将不胜感激。谢谢。

服务配置:

  <system.serviceModel>
<services>
  <service behaviorConfiguration="Lrs.Esf.Facade.Startup.FacadeBehavior"
    name="Lrs.Esf.Facade.Startup.FacadeService">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="default" contract="Lrs.Esf.Facade.Startup.IFacadeService">
      <identity>
        <servicePrincipalName value="lrsdomain/PensionDev" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<bindings>
  <wsHttpBinding>
    <binding name="default">
      <security mode="None"/>
    </binding>
  </wsHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="Lrs.Esf.Facade.Startup.FacadeBehavior">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true" />
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="true" />

    </behavior>
  </serviceBehaviors>
</behaviors>

客户端配置:

  <system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_IFacadeService" closeTimeout="00:01:00"
        openTimeout="00:01:00" receiveTimeout="00:1:00" sendTimeout="00:01:00"
        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
        maxBufferPoolSize="52428800" maxReceivedMessageSize="6553600"
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
        allowCookies="false">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
          maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <security mode="None">          
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://esf2.facade.testpe.pg.local/FacadeWcf/FacadeService.svc"
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFacadeService"
      contract="FacadeServiceReference.IFacadeService" name="WSHttpBinding_IFacadeService">
    <identity>
      <servicePrincipalName value="lrsdomain/PensionDev" />
    </identity>
  </endpoint>
</client>

【问题讨论】:

  • 我已经运行了 Fiddler 并对客户端进程进行了完整跟踪,并获得了更多信息。响应消息会在几秒钟后返回到客户端计算机(提琴手),但消息日志跟踪和“通过通道接收消息”直到 40 分钟后才会被记录。我的猜测是反序列化消息需要 40 分钟。
  • 我将服务主机从 IIS 中取出并创建了一个 TCP 端点,来自客户端 PC 的调用现在在 5 秒内返回。我现在的假设是 wsHTTP 中存在错误,或者 wsHTTP 或 IIS 中的设置我丢失了。
  • 我启用了 WAS/TCP 并向 IIS 托管服务添加了一个 TCP 端点。通过 TCP 调用只需要几秒钟,但通过 HTTP(basic 或 ws)调用仍然需要 40 分钟。

标签: wcf timeout wcf-binding


【解决方案1】:

您并没有增加服务器端各种参数的大小,看来-您绝对应该尝试一下!在服务器端也使用客户端配置文件中的绑定配置 - 服务可能会阻塞,因为它仍然默认为 64K 消息大小。

此外,您的客户端绑定中的 receiveTimeout 有点有趣 - 它缺少一个零位:

<binding name="WSHttpBinding_IFacadeService" 
receiveTimeout="00:1:00" 

你应该使用receiveTimeout="00:01:00"

马克

【讨论】:

  • 谢谢马克。我不认为这些设置适用于服务器端,但我在你的建议之后尝试了它并没有改变结果。我还修复了超时。由于我在客户端收到有关消息大小的原始错误,因此我的假设是故障发生在那里而不是服务器上。超时没有被触发的事实非常令人困惑。这几乎就像 WCF 在客户端完成了对消息的处理并认为它会将控制权交还给客户端,但由于某种原因仍然处于阻塞状态。
  • 好的,很有趣 - 您真的没有在客户端上收到任何超时或其他错误吗?这有点奇怪......
  • 您在服务器的事件日志中看到任何条目吗?也许 IIS 在日志中放了一些东西?似乎很奇怪,根本什么都没有......
  • 只是为了它 - 你能写你自己的服务主机(一个控制台应用程序,它实例化一个 ServiceHost 并调用 .Open() 和它),看看它是否有效?您还需要为服务器上的端点指定基地址或显式地址(在这种情况下)
  • 完全没有超时。在杀死它之前,我让它运行了 15 分钟左右。日志中也没有错误。主机应用程序听起来不错。我会试一试的。谢谢你的想法,马克。
【解决方案2】:

我已经找出了问题的基本原因并找到了解决方法,但是额外的见解会很棒。

WCF 将数据集序列化为 XML 格式。我强制 DataSet 序列化为 byte[] 并且时间减少到 4 秒。一种猜测是转义 4MB XML 中的所有字符以使 HTTP 通信有效是导致问题的原因。

【讨论】:

  • 又一个不在服务合同中使用 .NET 特定类型的原因。
  • 我读过约翰。那么,当您需要通过网络传输数据集时,您有什么建议。序列化为 JSON 并在另一端反序列化?
  • 我做了一些进一步的调查,返回的数据集包含一行和一列,但该列的值本身是 XML 并且相当大。我通过在 WCF 参与之前以不同的方式序列化列的值来解决这个问题,从而避免了这个问题。
猜你喜欢
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多