2016-06-24 8 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で待って呼び出して通話を遮断

    • リソースポーリング
    • :私はのための二重のチェックをお勧めします

    第2に、アプリケーションでは、Mutexesやその他のスレッド同期を使用しないでください。もしそうなら、あなたはライブロックに苦しんでいるかもしれません。デッドロックとは異なり、ライブロックは100%CPU使用率などの症状を示し、スレッドは常に「同時実行」プリミティブをロックしてロックを解除し、「すべてをキャッチ」します。 Wikipediaには、ライブロックがどのように見えるかの技術的な説明があります。 Akkaを適切に配置すると、Mutexesやスレッド同期プリミティブを使用する必要はありません。もしあなたがそうなら、たぶんあなたのアプリケーションを再設計する必要があります。

    第3のIO(と再接続の試行のようなエラー処理)を抑制する必要があります。この問題は、システムに効果的なスロットリングがないために発生している可能性があります。多くの場合、データチャネルでは、帯域幅は制約されません。しかし、これは、そのチャネルが100%飽和に達し、システムの他の部分からリソースを奪い始めると問題になる可能性があります。これは、たとえば、大きなファイルを妥当な制限なしに移動している場合に発生します。

    また、直ちに再試行するのではなく、エラーが発生したときに接続の再試行を抑制する必要があります。多くのシステムでは、接続が失われた場合にサーバーに再接続しようとします。通常は望ましいですが、これは単純な再接続戦略を使用すると問題のある動作につながります。たとえば、次のように書かれたネットワーククライアントを想像してみてください。

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

    何らかの理由でクライアントが接続を切断すると、再接続が試みられます。 Wifiカットアウトまたはネットワークケーブルのプラグが抜かれた場合、エラー処理コードとクライアントの間でどのようにタイトなループが発生するかを確認できます。

    第4、アプリケーションには、データソースとシンクが明確に定義されている必要があります。あなたの問題は、チェーン内の次のアクタにメッセージを送信している最後のアクタがチェーン内の最初のアクタにメッセージを送り返しているAkkaアクタの一部である「データループ」によって引き起こされる可能性があります。メッセージをシステムに入力して終了するための明確かつ明確な方法があることを確認してください。

    第5、は、アプリケーションに適切なプロファイリングと計測を使用します。KamonまたはCoda Hale's Metricsライブラリを使用してアプリケーションを計測します。

    適切なプロファイラを見つけることは、リアクションアプリケーションのための成熟したツールを開発するコミュニティには遠く離れているため、より困難になります。個人的に私はvisualvmが有用だが、CPUに束縛されているコードパスを検出するのに必ずしも圧倒的に役立つとは限りません。問題は、サンプリングプロファイラーはJVMがセーフポイントに達したときにのみデータを収集できることです。これにより、特定のコードパスをバイアスする可能性があります。この問題を解決するには、AsyncGetStackTraceをサポートするプロファイラを使用します。

    運が良かった!できるだけ多くの文脈を追加してください。

  • 関連する問題