2014-04-21 10 views
3

내 회사에서 Azure 서비스 버스 릴레이를 사용하여 중요한 데이터의 요약을 Azure 호스트 응용 프로그램에 집계합니다. 우리는 프로덕션 전 서버에서 처음 몇 개의 요청이 처리 된 후 ServiceHost 인스턴스를 호스팅하는 프로세스의 CPU 사용률이 최대 70-90 %까지 올라가고 거기에 머물러 있다는 것을 알았습니다. ServiceHost는 일반적으로 Windows 서비스에서 자체 호스팅되지만 다양한 설정 및 테스트 시나리오를 위해 실행하는 WPF 앱이 있으며이 동작을 두 가지 모두에서 재현 할 수 있습니다. 개발 환경에서이 동작을 재현 할 수 없었습니다.유휴 ServiceHost의 높은 CPU가 Azure 서비스 버스 릴레이에 연결됨

나는 코드를 검토하고 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 계층에 의해 잡히고 결코 회사의 코드를 포기하지 않습니다. // [name_redacted] .servicebus.windows.net : 9350/추적에 의해 촬영 된 고유의 예외 메시지가

가 net.tcp 연결할 수 없습니다이었다. 연결 시도는 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의 서명이 있습니다. 내 이해는 캡처 중에 프로세스에 서비스 버스 호출이 없었기 때문에이 스레드가 무엇을 수행했는지 확신 할 수 없습니다.

다음 단계에서는 서버에서 perfmon 캡처를 실행하고 결과가 분명해 지는지 확인합니다. 나는 서버에 직접 액세스 할 수 없기 때문에 실습 분석을하기 위해 SysAdmin으로 시간을 예약해야합니다.

누가이 숨겨진 CPU 스파이크의 원인이 될 수있는 아이디어가 있습니까? Azure Service Bus Relay 또는 WCF에서이 동작을 수행하는 것으로 알려진 것이 있습니까? 어떤 제안이라도 대단히 감사하겠습니다.

답변

1

예기치 않은 ACK \ FIN 패킷으로 높은 CPU가 트리거되고있는 것으로 나타났습니다. 우리는 방화벽이 실제로 외부 연결을 닫으려고하는 것임을 의심합니다. 우리는 악의적 인 ACK \ FIN 패킷을 주입하여 다른 장치에서 문제를 재현 할 수있었습니다.

예기치 않은 패킷을보다 잘 처리 할 수 ​​있도록 Microsoft Azure 팀에 문의하고 있습니다. 우리는 또한 네트워크 방화벽 팀에게 패킷 전송을 격리시키고 제거하려고 노력할 것입니다.