我的公司正在使用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立即返回空闲。
我已经做了一个跟踪侦听器,但是唯一的消息是在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转储开始,但认为一个快照无法给我提供关于随着时间推移所发生的事情的足够信息,所以我找到了Saffron关于生产.Net应用程序CPU分析的博客文章。我们抓取了cpu分析器的最新版本的源代码,并在有问题的服务器上运行它。所有最昂贵的栈都有System.Threading._IOCompletionCallback.PerformIOCompletionCallback的签名。我的理解是在捕获过程中没有服务总线调用,所以我不知道这个线程会做什么。
接下来的步骤是在服务器上运行perfmon捕获,并查看结果,看看是否有明显的结果出现在我们身上。我没有直接访问服务器的权限,因此需要使用SysAdmin来安排时间,这样才能进行手动的analysys操作。
有没有人知道是什么原因导致了这个隐藏的CPU尖峰?在Azure Service Bus Relay或WCF中是否存在此行为?如有任何建议,将不胜感激。
发布于 2014-06-18 13:17:07
原来,高CPU是由意外的ACK\FIN数据包触发的。我们怀疑防火墙是真正发送的,试图关闭外部连接。我们只需注入流氓ACK\FIN数据包,就可以在其他设备上重新创建这个问题。
我们正在跟踪微软Azure团队,试图让他们更好地处理意外的数据包。我们还将跟踪网络防火墙团队,试图隔离和消除数据包被发送。
https://stackoverflow.com/questions/23198377
复制相似问题