wcf - 连接到 Azure 服务总线中继的空闲 ServiceHost 上的 CPU 利用率较高

标签 wcf azure servicebus servicehost azure-servicebusrelay

我的公司正在使用 Azure 服务总线中继将敏感数据摘要聚合到 Azure 托管的应用程序中。我们注意到,在预生产服务器上,在处理前几个请求后,托管 ServiceHost 实例的进程的 CPU 利用率会跃升至 70-90% 并保持在该水平。 ServiceHost 通常在 Windows 服务中自托管,但我们也有一个 WPF 应用程序,我们可以在其下运行它以进行各种设置和测试场景,并且我们可以在两者上重现此行为。我们无法在我们的开发环境中重现此行为。

我查看了代码并将其与 MSDN 上的示例进行了比较,对我来说它们看起来是相同的。这是精简版:

ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;
this.serviceBusUri = ...;
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(...,...);
ContractDescription contractDescription = ContractDescription.GetContract(typeof(IOurServiceProxy), typeof(OurServiceProxy));
NetTcpRelayBinding binding = new NetTcpRelayBinding(EndToEndSecurityMode.Transport, RelayClientAuthenticationType.RelayAccessToken, true);
binding.ConnectionMode = TcpRelayConnectionMode.Relayed;
this.serviceEndpoint = new ServiceEndpoint(contractDescription);
this.serviceEndpoint.Address = new EndpointAddress(this.serviceBusUri);
this.serviceEndpoint.Binding = binding;
this.serviceEndpoint.Behaviors.Add(sharedSecretServiceBusCredential);
this.host = new ServiceHost(typeof(OurServiceProxy), this.serviceBusUri);
this.host.Description.Endpoints.Add(this.serviceEndpoint);
this.host.Open();
this.host.Faulted += OnFaulted;

我们从未见过触发 OnFaulted 事件处理程序,并且在 CPU 跳转后继续处理请求。 WPF 版本的主机应用程序有一个按钮,可以通过调用 this.host.Close() 来断开与服务总线的连接,一旦断开连接,CPU 立即返回空闲状态.

我已经完成了跟踪监听器,但唯一的消息与 ServiceHost 启动时自动检测 SystemConnectivity.Mode 相关。堆栈中的错误位置是对 Microsoft.ServiceBus.NetworkDetector.DetectInternalConnectivityModeForAutoDetect(Uri uri) 的调用的后续结果。错误本身被 Microsoft.ServicBus 层捕获,并且永远不会冒泡到我公司的代码中。跟踪捕获的具体异常消息为

Could not connect to net.tcp://[name_redacted].servicebus.windows.net:9350/. The connection attempt lasted for a time span of 00:00:01.1856021. TCP error code 10061: No connection could be made because the target machine actively refused it [ip_redacted]:9350.

这是我用于跟踪的设置:

   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" 
                    switchValue="Warning, Error, Critical"
                    propagateActivity="true">
            <listeners>
               <add name="traceListener" 
                   type="System.Diagnostics.XmlWriterTraceListener" 
                   initializeData= "C:\Temp\Traces.svclog" />
            </listeners>
         </source>
      </sources>
   </system.diagnostics>

接下来我尝试对哪些线程消耗了所有 CPU 进行了一些分析。我从进程的内存转储开始,但认为单个快照无法为我提供有关一段时间内发生的情况的足够信息,因此我找到了 Sam Saffron's blog post about CPU analysis for a production .Net application 。我们获取了最新版本的 cpu-analyzer 源代码,并在有问题的服务器上运行它。所有最昂贵的堆栈在基础上都有一个 System.Threading._IOCompletionCallback.PerformIOCompletionCallback 的签名。我的理解是,在捕获期间没有服务总线调用进程,因此我不确定该线程会做什么。

我们接下来的步骤是在服务器上运行 perfmon 捕获,并查看结果,看看是否有任何明显的情况出现。我无法直接访问服务器,因此需要与系统管理员安排时间以便进行实际分析。

有人知道是什么原因导致了这个隐藏的 CPU 峰值吗?是否有已知的东西可以在 Azure 服务总线中继或 WCF 中执行此行为?任何建议将不胜感激。

最佳答案

事实证明,CPU 占用率过高是由意外的 ACK\FIN 数据包触发的。我们怀疑防火墙实际上是发送此消息的,试图关闭外部连接。我们只需注入(inject)恶意 ACK\FIN 数据包即可在其他设备上重现该问题。

我们正在与 Microsoft Azure 团队跟进,试图让他们更好地处理意外数据包。我们还将与网络防火墙团队跟进,尝试隔离并消除数据包的发送。

关于wcf - 连接到 Azure 服务总线中继的空闲 ServiceHost 上的 CPU 利用率较高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23198377/

相关文章:

c# - 长轮询实际上如何在客户端调用回调?

已过期 MSDN 订阅的 Azure 积分仍然有效

azure - 如何使用参数自动从 Azure Web 应用程序获取完整内存转储

c# - BrokeredMessage 已处置

nservicebus - 使用服务总线从由 Web 应用程序组成的服务层发布事件

WCF 服务授权管理器设置 Thread.CurrentPrincipal

c# - 输入不是有效的 Base64 字符串,因为它在 C# 中包含非 base 64 字符?

c# - 对应 map 缩放/移动 Action 的Transform Path/Polyline

Azure 应用服务访问文件存储以使用 webjob 复制内容

azure - 使用 ReceiveMode.ReceiveAndDelete 处理在 Azure 暂存中运行的 ServiceBus 主题订阅者的技术