Ohne den Quellcode zu sehen oder zu wissen, über welchen IO-Kanal Sie sprechen (Sockets, Dateien, usw.), gibt es kaum einen Einblick, den Ihnen jemand hier geben kann.
Ich habe jedoch einige ziemlich allgemeine Vorschläge.
Zuerst, sollten Sie reaktive Techniken und reaktive IO in Ihrer Anwendung verwenden. Dieses Problem kann auftreten, weil Sie den Status einiger Ressourcen in einer engen Schleife abrufen oder einen blockierenden Aufruf verwenden, wenn Sie einen reaktiven verwenden sollten. Dies neigt dazu, ein Anti-Pattern- und ein Performance-Drain genau zu sein, weil Sie CPU-Zyklen ausgeben können, die nichts als "aktiv warten" tun. Ich empfehle doppelte Kontrolle für:
- Ressource Polling
- Blockierung auf einem
Future
- System ruft
- Plattenwallungen
- warten ruft, wenn es um
map
stattdessen angemessen wäre es
Zweitens, sollten Sie nicht Mutexes oder andere Thread-Synchronisation in Ihrer Anwendung verwenden. Wenn ja, dann leiden Sie möglicherweise an einer Live-Sperre. Im Gegensatz zu Dead-Locks treten bei Live-Locks Symptome wie 100% CPU-Auslastung auf, da Threads immer wieder Concurrency-Primitive sperren und entsperren, um "alle zu fangen". Wikipedia hat eine nette technische Beschreibung, wie ein Live-Schloss aussieht. Mit Akka sollten Sie keine Mutexes oder Grundelemente für die Thread-Synchronisation benötigen. Wenn Sie dann sind, müssen Sie wahrscheinlich Ihre Anwendung neu entwerfen.
Drittens, sollten Sie IO (sowie Fehlerbehandlung wie Wiederverbindungsversuche) Drosselung sein. Dieses Problem kann auftreten, weil Ihr System keine effektive Drosselung aufweist. Oft verlassen wir bei Datenkanälen ihre Bandbreite unbeschränkt. Dies kann jedoch ein Problem werden, wenn dieser Kanal 100% Sättigung erreicht und beginnt, Ressourcen von anderen Teilen des Systems zu stehlen. Dies kann zum Beispiel passieren, wenn Sie große Dateien ohne ein vernünftiges Limit verschieben.
Alternativ müssen Sie Verbindungswiederholungen bei Auftreten von Fehlern drosseln, anstatt sie sofort erneut auszuführen. Viele Systeme versuchen, die Verbindung zu einem Server wiederherzustellen, wenn sie ihre Verbindung verlieren. Obwohl dies normalerweise wünschenswert ist, kann dies zu einem problematischen Verhalten führen, wenn Sie eine naive Wiederverbindungsstrategie verwenden.Zum Beispiel vorstellt, einen Netzwerk-Client, der auf diese Weise geschrieben wurde:
class MyClient extends Client {
... other code...
def onDisconnect() = {
reconnect()
}
}
Jedes Mal, wenn der Client für irgendeinen Grund trennt sie versucht, wieder zu verbinden. Sie können sehen, wie dies zu einer engen Schleife zwischen dem Fehlerbehandlungscode und dem Client führen würde, wenn der Wifi-Ausgang oder ein Netzwerkkabel nicht angeschlossen wäre.
Vierte, Ihre Anwendung sollte gut definierte Datenquellen und Senken haben. Ihr Problem könnte durch eine "Datenschleife" verursacht werden, dh durch eine Gruppe von Akka-Akteuren, die nur Nachrichten an den nächsten Akteur in der Kette senden, wobei der letzte Akteur die Nachricht an den ersten Akteur in der Kette zurücksendet. Stellen Sie sicher, dass Sie eine eindeutige und eindeutige Möglichkeit haben, Nachrichten in Ihr System einzugeben und es zu beenden.
Fünftens, Verwenden Sie geeignete Profilierung und Instrumentierung für Ihre Anwendung. Instrumentieren Sie Ihre Anwendung mit der Kamon oder Coda Hale Metrics-Bibliothek.
Die Suche nach einem geeigneten Profiler wird schwieriger, da wir als Gemeinschaft weit davon entfernt sind, ausgereifte Werkzeuge für reaktive Anwendungen zu entwickeln. Persönlich habe ich gefunden visualvm
nützlich, aber nicht immer überwältigend hilfreich für die Erkennung von Code-Pfaden, die CPU-gebunden sind. Das Problem besteht darin, dass Stichproben-Profiler nur Daten erfassen können, wenn die JVM einen Sicherheitspunkt erreicht. Dies hat das Potenzial, bestimmte Codepfade zu beeinflussen. Das Problem besteht darin, einen Profiler zu verwenden, der AsyncGetStackTrace
unterstützt.
Viel Glück! Und fügen Sie bitte mehr Kontext hinzu, wenn Sie können.
Sie sagen, Sie haben eine CPU-Probe genommen. Was genau meinst du? –
sun.misc.Unsafe ist keine Methode, es ist eine Klasse. Bitte zeigen Sie die vollständige Stack-Trace. –