WCF延迟问题

时间:2012-02-08 01:05:59

标签: wcf

我有一个自托管的F#WCF服务器,用于将缓存的数据返回给我们的应用程序。数据量可以从单行到数万。由于数据差异很大,我在app.config中设置值来处理非常大的数据项。一切都工作正常,直到一周前出现问题,服务器刚停止工作。我花了几天时间才得到东西,我从未弄清楚到底出了什么问题。我使用了服务实用程序并调整了设置,直到我再次使用它。问题是它增加了1.2秒的延迟,这是以前没有的。我一遍又一遍地调整设置并阅读我能找到的每篇文章,似乎没有任何帮助。我有netTcp和Ws的设置,但我正在使用netTcp设置。 (可能有一些设置不需要在那里,但我想把整个事情放在这里,以防有一些我不知道的冲突。) 这是app.config文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IPrevisionServer"  closeTimeout="00:01:00"
          openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
          hostNameComparisonMode="StrongWildcard"
          maxBufferSize="2147483647"
          maxBufferPoolSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647"
            maxStringContentLength="2147483647"
            maxArrayLength="2147483647"
            maxBytesPerRead="2147483647"
            maxNameTableCharCount="2147483647" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IPrevisionServer" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
            maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
            messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
            allowCookies="false">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
              maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <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>
    <services>
      <service behaviorConfiguration="PrevisionSerializer"
       name="PrevisionServer.PrevisionService">
        <endpoint  address="net.tcp://192.168.101.100:2009/PrevisionService/tcp"
          binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPrevisionServer"
          contract="IPrevisionServer" name="NetTcpBinding_IPrevisionServer">
        </endpoint>
      </service>
    </services>
    <client>
      <endpoint address="http://192.168.101.100:2008/PrevisionService/ws/ws"
          binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IPrevisionServer" behaviorConfiguration="ServiceViewEventBehavior"
          contract="IPrevisionServer" name="WSHttpBinding_IPrevisionServer">
        <identity>
          <userPrincipalName value="ecloward@hcg" />
        </identity>
      </endpoint>
      <endpoint address="net.tcp://192.168.101.100:2009/PrevisionService/tcp" behaviorConfiguration="ServiceViewEventBehavior"
          binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPrevisionServer"
          contract="IPrevisionServer" name="NetTcpBinding_IPrevisionServer">
        <identity>
          <userPrincipalName value="ecloward@hcg" />
        </identity>
      </endpoint>
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="HttpGetMetadata">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
        <behavior name="PrevisionSerializer">
          <dataContractSerializer ignoreExtensionDataObject="true" maxItemsInObjectGraph="2147483647" />
          <serviceTimeouts transactionTimeout="01:00:00" />
          <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000"
            maxConcurrentInstances="1000" />
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="ServiceViewEventBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    </system.serviceModel>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="wcfTraceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WcfClientTrace.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

我想使用WCF,但在完成所有这些工作时,我想知道是否应该查看原始套接字?如果您有其他想要查看的代码,请告诉我,但它非常复杂,所以我不想发布所有代码。

更新: Per Richard Blewett,我将解释我正在尝试做什么,并且有关配置此功能的最佳方法的任何指导都会很棒。

基本上,我将大部分业务逻辑转移到app服务器,因为它现在的大部分都包含在SQL Server存储过程中,我们发现由于查询的复杂性,SQL也是如此慢。通过查询SQL,使用应用服务器上的F#库转换数据,然后缓存它,我发现我可以将每个请求的时间从20-60秒下降到数据缓存后的不到3秒,尽管大多数这是由于上述延迟问题。我知道在某些情况下3秒可能没问题,但我知道它可以更快,因为它以前工作,最终我们希望这部署在云解决方案上然后将涉及1000个用户,所以我希望这个能够很好地扩展。

我们返回的数据类型通常少于10列,每列通常是少于100个字符或小数的字符串。但是数据会有很多行,从几百到几万不等。客户端的数量范围从一小部分到一次可能达到100或更多(尽管目前这个级别的客户很少)。将部署在我们各种客户端站点上的应用程序,但稍后将部署在云解决方案中。

由于数据主要用于报告,因此大多数调用都是只读数据,因此是缓存。通常用户运行报告,修改参数,然后再次运行报告,这样就会立即调用大量数据,然后几秒钟或几分钟就没有。虽然用户将连续运行一系列报告(通常是数百个),因此会有一些批量报告流程,因此会有大量的数据调用,一次又从几百行到几十万。

我希望这足以继续下去。再次感谢!

1 个答案:

答案 0 :(得分:0)

如果您正在追踪速度,请删除WSHttpBinding周围的所有条目 - 这只是令人困惑的问题。

MTOM只有在使用文本XML以可互操作的方式发送二进制文件时才有用 - 您正在使用带有NetTcpBinding的二进制编码器,因此线上的数据已经是二进制的

我怀疑您已启用之前已关闭的服务中的安全性,这是您看到性能差异的地方。

在服务中抛出配置可能会“让事情变得有效”,但以后可能会引发重大问题。例如,您已将接收超时设置为一小时。这意味着如果客户端没有关闭其代理,则需要一小时才能确定客户端没有回来,因此它将为该客户端维护一小时的会话资源

如果您详细说明了您在超时,邮件大小和安全性方面的要求,那么我们可以帮助您获得符合要求的配置