2016-06-24 2 views
2

끊임없이 100 % CPU 사용률을 유지하는 Akka 응용 프로그램을 프로파일하려고합니다. 나는 visualvm을 사용하여 CPU 샘플을 채취했다. 샘플에서는 CPU 사용량의 98.9 %를 차지하는 스레드가 2 개 있음을 나타냅니다. CPU 시간의 79 %는 sun.misc.Unsafe이라는 방법에 사용되었습니다. Other answers on SO은 스레드가 대기 중이지만 기본 구현 계층 (jvm 외부)에 있다는 것을 의미합니다.Akka IO 응용 프로그램이 100 % CPU를 사용합니다.

광산과 비슷한 질문에서 사람들은 구체적으로 알려지지 않은 채 told to look elsewhere되었습니다. 무엇이 CPU 스파이크의 원인인지 알아 내야합니까?

응용 프로그램은 주로 Akka IO를 사용하여 TCP 소켓 연결을 수신하는 서버입니다.

+0

당신은 CPU 샘플을 가져 갔다고합니다. 정확하게 무슨 뜻입니까? –

+0

sun.misc.Unsafe는 메소드가 아니며 클래스입니다. 전체 스택 추적을 보여주십시오. –

답변

2

소스 코드를 보지 않고 (소켓, 파일 등) 말하는 IO 채널을 알지 못하더라도 여기있는 사람이 당신에게 줄 수있는 통찰력은 거의 없습니다.

다소 일반적인 제안이 있습니다.

먼저 사용자는 응용 프로그램에서 반응 기술 및 반응식 IO를 사용해야합니다.이 문제는 엄격한 루프에서 일부 리소스의 상태를 폴링 중이거나 반응이있는 리소스를 사용해야 할 때 차단 호출을 사용하기 때문에 발생할 수 있습니다. 이는 CPU주기가 "활발히 대기"하면서 아무것도 할 수 없기 때문에 정확하게 패턴을 방지하고 성능을 저하시키는 경향이 있습니다.

  • 자원 폴링
  • 차단이
    • 시스템이 그것을 대신 map
    적합 할 때 Future 기다리고
  • 디스크 플러시
  • 를 호출 전화 : 내가 두 번 검사를 권장합니다

둘째, 은 응용 프로그램에서 뮤텍스 또는 다른 스레드 동기화를 사용하면 안됩니다. 그렇다면 실시간 잠금 장치로 인해 문제가 발생할 수 있습니다. 데드 록과는 달리 실시간 잠금은 스레드가 지속적으로 동시성 프리미티브를 잠 그거나 잠금 해제하여 "모두 포착"하려고하는 것처럼 100 % CPU 사용량과 같은 증상을 나타냅니다. Wikipedia에는 라이브 잠금이 어떻게 보이는지에 대한 훌륭한 기술 설명이 있습니다. Akka를 사용하면 Mutexes 또는 모든 스레드 동기화 프리미티브를 사용할 필요가 없습니다. 그렇다면 아마 응용 프로그램을 다시 디자인해야 할 것입니다.

세 번째로 은 IO (조정 및 재 연결 시도와 같은 오류 처리)를 조절해야합니다. 시스템에 효과적인 스로틀이 없기 때문에이 문제가 발생할 수 있습니다. 종종 데이터 채널을 사용하여 대역폭을 제한하지 않습니다. 그러나 채널이 100 % 채도에 도달하여 시스템의 다른 부분에서 자원을 도용하기 시작하면 문제가 될 수 있습니다. 예를 들어 합리적인 제한없이 대용량 파일을 옮기는 경우 이런 일이 발생할 수 있습니다.

또는 오류가 발생하면 즉시 다시 시도하지 말고 연결 재 시도를 제한해야합니다. 많은 시스템은 연결이 끊어지면 서버에 다시 연결을 시도합니다. 일반적으로 바람직하지만 순진한 재 연결 전략을 사용하면 문제가 발생할 수 있습니다.예를 들어, 이렇게 작성된 네트워크 클라이언트를 상상해보십시오.

class MyClient extends Client { 
... other code... 
    def onDisconnect() = { 
    reconnect() 
    } 
} 

클라이언트가 어떤 이유로 연결을 끊을 때마다 다시 연결을 시도합니다. Wifi 차단 또는 네트워크 케이블이 분리 된 경우 이것이 오류 처리 코드와 클라이언트간에 긴밀한 루프를 일으키는 지 확인할 수 있습니다.

넷째, 응용 프로그램에 데이터 소스와 싱크가 잘 정의되어 있어야합니다. 문제는 체인의 다음 액터로 메시지를 보내는 Akka 액터의 일부인 "데이터 루프"로 인해 발생할 수 있습니다. 마지막 액터는 메시지를 체인의 첫 번째 액터로 다시 보냅니다. 메시지가 시스템에 들어가고 나갈 수있는 확실하고 명확한 방법이 있는지 확인하십시오.

다섯 번째로, 은 응용 프로그램에 적합한 프로파일 링 및 계측을 사용합니다.Kamon 또는 Coda Hale 's Metrics 라이브러리를 사용하여 응용 프로그램을 계측하십시오.

반응 형 애플리케이션을위한 성숙한 도구를 개발하기 위해 커뮤니티가 멀기 때문에 적절한 프로파일 러를 찾는 것이 더 어려울 것입니다. 개인적으로 나는 visualvm이 유용하다는 것을 알았지 만, CPU의 코드 경로를 탐지하는데 항상 도움이되는 것은 아닙니다. 문제는 샘플링 프로파일 러가 JVM이 safepoint에 도달했을 때만 데이터를 수집 할 수 있다는 것입니다. 이것은 특정 코드 경로를 바이어스 할 가능성이 있습니다. 수정은 AsyncGetStackTrace을 지원하는 프로파일 러를 사용하는 것입니다.

행운을 빈다. 가능한 경우 추가 컨텍스트를 추가하십시오.

관련 문제