我的公司正在使用Azure Service Bus Relay将敏感数据的摘要聚合到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立即返回空闲状态。
我已经完成了跟踪侦听器,但唯一的消息与SystemConnectivity.Mode
启动时ServiceHost
的自动检测有关。堆栈中的错误位置是对Microsoft.ServiceBus.NetworkDetector.DetectInternalConnectivityModeForAutoDetect(Uri uri)
的调用的中断。故障本身被Microsoft.ServicBus层捕获,并且永远不会冒泡到我公司的代码。跟踪捕获的特定异常消息是
无法连接到net.tcp:// [name_redacted] .servicebus.windows.net:9350 /。连接 尝试持续了00:00:01.1856021的时间跨度。 TCP错误代码 10061:无法建立连接,因为目标计算机是主动的 拒绝了它[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进行一些分析。我开始使用这个过程的mem转储,但是我决定单个快照无法提供足够的信息,因为我发现 Sam Saffron's blog post about CPU analysis for a production .Net application 。我们抓住了cpu-analyzer的最新版本的源代码并在有问题的服务器上运行它。所有最昂贵的堆栈在基础上都有System.Threading._IOCompletionCallback.PerformIOCompletionCallback
的签名。我的理解是在捕获期间没有Service Bus调用进程,所以我不确定这个线程会做什么。
我们接下来的步骤是在服务器上运行perfmon捕获并查看结果,看看是否有任何明显的突然出现在我们身上。我无法直接访问服务器,因此需要使用SysAdmin安排时间,以便进行实际操作分析。
有没有人知道可能导致这种隐藏的CPU峰值的原因是什么?在Azure Service Bus Relay或WCF中是否有任何已知的行为?任何建议都将不胜感激。
答案 0 :(得分:1)
事实证明,高CPU正在被意外的ACK \ FIN数据包触发。我们怀疑防火墙是实际发送的,试图关闭外部连接。我们只需注入流氓ACK \ FIN数据包即可在其他设备上重新创建问题。
我们正在跟进Microsoft Azure团队,试图让他们更好地处理意外数据包。我们还将跟进网络防火墙团队,尝试隔离并消除数据包的发送。