【发布时间】:2014-06-05 13:48:51
【问题描述】:
我的公司正在使用 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 层捕获,并且永远不会冒泡到我公司的代码中。跟踪捕获的特定异常消息是
无法连接到 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。我从进程的内存转储开始,但认为单个快照无法为我提供有关随着时间推移发生的事情的足够信息,因此我找到了 Sam Saffron's blog post about CPU analysis for a production .Net application。我们获取了最新版本的 cpu-analyzer 源代码并在相关服务器上运行它。所有最昂贵的堆栈在底部都有System.Threading._IOCompletionCallback.PerformIOCompletionCallback 的签名。我的理解是在捕获过程中没有服务总线调用进入进程,所以我不确定这个线程会做什么。
我们接下来的步骤是在服务器上运行 perfmon 捕获并查看结果,看看是否有任何明显的问题出现在我们面前。我没有直接访问服务器的权限,因此需要与 SysAdmin 安排时间以便进行动手分析。
有没有人知道是什么导致了这个隐藏的 CPU 峰值?在 Azure 服务总线中继或 WCF 中是否有任何已知的行为?任何建议将不胜感激。
【问题讨论】:
标签: wcf azure servicebus servicehost azure-servicebusrelay