2

我目前正在开发一个具有 SOA 架构的应用程序,服务公开为 WCF 服务(.Net 4.0),托管在 Windows Server 2008 R2 Datacenter x64 VM 上的 IIS 7.5 中(它实际上是 Amazon EC2 上的 m1.small 实例)。这些服务在机器上本地相互通信,因此我已将它们设置为使用 netNamedPipeBinding 以获得最佳性能。实例化模式是每次调用,并发设置为多个。

目前我遇到了两个问题,即在打开 200 毫秒到 1 秒之间的通道时出现间歇性延迟,这是不可接受的,因为正常速度似乎约为 2 毫秒。

我启用了 WCF 跟踪,我看到延迟表现为以下错误:

System.IO.PipeException:写入管道时出错:管道正在关闭。(232, 0xe8)。

之后它出现 WCF 重试并成功连接(因此延迟)。第二个症状是执行活动时延迟半秒:

处理操作“http://tempuri.org/IConnectionRegister/ValidateUriRoute”

我唯一能找到的就是有些人认为它可能与 TCP 端口共享有关,但我使用的是命名管道。我尝试禁用 TCP 端口共享服务,但这没有任何区别。

出于兴趣,我还尝试将所有端点更改为使用 net.tcp 在同一随机端口上的 localhost 上侦听,并且ValidateUriRoute活动中的半秒延迟仍然间歇性地发生。

我的 WCF 配置与此类似:

<system.serviceModel>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
                               multipleSiteBindingsEnabled="false">

      <serviceActivations>

        <add relativeAddress="ConfigurationHost.svc" service="Core.ConfigurationHost" factory="Core.ConfigurationHostFactory" />
        <add relativeAddress="RoutingHost.svc" service="Core.RoutingHost" factory="Core.RoutingHostFactory" />
        <add relativeAddress="AuthenticationHost.svc" service="Core.AuthenticationHost" factory="Core.AuthenticationHostFactory" />

      </serviceActivations>

    </serviceHostingEnvironment>

    <services>

      <service name="Core.ConfigurationHost"
               behaviorConfiguration="Unthrottled">

        <endpoint address="net.pipe://localhost/ConfigurationHost.svc"
                  binding="netNamedPipeBinding"
                  bindingConfiguration="customNetNamedPipeBinding"
                  contract="Core.IConfiguration" />

      </service>

      <service name="Core.RoutingHost"
               behaviorConfiguration="Unthrottled" >

        <endpoint address="net.pipe://localhost/RoutingHost.svc"
                  binding="netNamedPipeBinding"
                  bindingConfiguration="customNetNamedPipeBinding"
                  contract="Core.IRouting" />

      </service>

      <service name="Core.AuthenticationHost"
               behaviorConfiguration="Unthrottled">

        <endpoint address="net.pipe://localhost/AuthenticationHost.svc"
                  binding="netNamedPipeBinding"
                  bindingConfiguration="CustomNetNamedPipeBinding"
                  contract="Core.IAuthentication" />

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior  name="Unthrottled">

          <serviceThrottling maxConcurrentCalls="100"
                             maxConcurrentSessions="100"
                             maxConcurrentInstances="100" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <client>

      <endpoint address="net.pipe://localhost/ConfigurationHost.svc"
                binding="netNamedPipeBinding"
                bindingConfiguration="customNetNamedPipeBinding"
                contract="Core.IConfiguration"
                name="Configuration" />

      <endpoint address="net.pipe://localhost/RoutingHost.svc"
                binding="netNamedPipeBinding"
                bindingConfiguration="customNetNamedPipeBinding"
                contract="Core.IRouting"
                name="Routing" />

      <endpoint address="net.pipe://localhost/AuthenticationHost.svc"
                binding="netNamedPipeBinding"
                bindingConfiguration="customNetNamedPipeBinding"
                contract="Core.IAuthentication"
                name="Authentication" />

    </client>

    <bindings>

      <netNamedPipeBinding>

        <binding name="customNetNamedPipeBinding"
                 maxReceivedMessageSize="2147483647"
                 sendTimeout="00:00:30"
                 receiveTimeout="infinite"
                 closeTimeout="00:00:30"
                 openTimeout="00:00:30"
                 maxConnections="500">

          <security mode="None"/>

          <readerQuotas maxDepth="200"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />

        </binding>

      </netNamedPipeBinding>

    </bindings>

  </system.serviceModel>
4

1 回答 1

0

我认为这两个操作时间的间歇性信号很可能是命名管道和 TCP 绑定都使用的连接池机制的副产品。连接池有一个最大空闲时间,在此之后空闲连接将从池中删除。这会产生固有的竞争条件:有时可能会在另一方刚刚丢弃为空闲的连接上尝试建立 WCF 通道。

我自己没有尝试过,但是如果您更关心时间的一致性而不是绝对时间,您可以尝试调整绑定的传输绑定元素上的连接池设置,以禁用池(set MaxOutboundConnectionsPerEndpoint= 0)或减少空闲连接的发生率(更改IdleTimeout值)。

如果您无法完成这项工作,或者如果您认为延迟发生的时间比它们应该更长,甚至考虑到连接池引入的固有可变性,您可能需要 Microsoft 工程师的帮助,因为这些东西深入 WCF 实现的内部。

于 2012-07-12T13:47:10.707 回答