通道打开时的 WCF NetNamedPipeBinding 延迟
Posted
技术标签:
【中文标题】通道打开时的 WCF NetNamedPipeBinding 延迟【英文标题】:WCF NetNamedPipeBinding Delay On Channel Open 【发布时间】:2012-07-12 10:38:24 【问题描述】:我目前正在开发一个具有 SOA 架构的应用程序,服务公开为 WCF 服务 (.Net 4.0),托管在 Windows Server 2008 R2 Datacenter x64 VM 上的 IIS 7.5 中(它实际上是一个 m1.small 实例在 Amazon EC2 上)。这些服务在机器上本地相互通信,因此我已将它们设置为使用 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>
【问题讨论】:
【参考方案1】:我认为这两个操作时间的间歇性信号很可能是命名管道和 TCP 绑定都使用的连接池机制的副产品。连接池有一个最大空闲时间,在此之后空闲连接将从池中删除。这会产生固有的竞争条件:有时可能会在另一端刚刚丢弃为空闲的连接上尝试建立 WCF 通道。
我自己没有尝试过,但是如果您更关心时间的一致性而不是绝对时间,您可以尝试调整connection pool settings on the binding's transport binding element,以禁用池化(设置MaxOutboundConnectionsPerEndpoint
= 0)或减少空闲连接的发生率(更改IdleTimeout
值)。
如果您无法完成这项工作,或者如果您认为延迟发生时的时间超过了应有的时间,甚至考虑到连接池引入的固有可变性,您可能需要 Microsoft 工程师的帮助,因为这些东西在 WCF 实现的内部很深。
【讨论】:
以上是关于通道打开时的 WCF NetNamedPipeBinding 延迟的主要内容,如果未能解决你的问题,请参考以下文章