So lösen Sie die Probleme, die durch die drei Blockierungswarteschlangen von Java verursacht werden

Kürzlich haben ich und mein Programmierteam ein kleines Hindernis für den Anforderungsmechanismus der Anwendung entdeckt. Nach einigen Überprüfungen fand ich die Grundursache.

Störung und Diagnose

Der Thread-Pool zum Verarbeiten von Anforderungen für die Anwendung war voll und konnte keine zusätzlichen Anforderungen verarbeiten. Nach dem Ablegen der Threads stellte ich fest, dass der Thread-Stapel im Protokollschreibbereich blockiert war. Es ist kein neues Problem, dass der Thread-Stapel im Protokollschreibbereich blockiert ist, aber ich dachte früher, dies sei das Ergebnis von etwas anderem. Aufgrund früherer Erfahrungen haben wir daher angenommen, dass das Problem nicht im Protokollschreibbereich liegt.

Nachdem wir viele Fehlerbehebungs- und Frustrationsmaßnahmen durchgeführt hatten, ohne die Hauptursache des Problems zu finden, haben wir uns den Quellcode angesehen und versucht, Hinweise darauf zu erhalten, was das Problem verursacht hat. .. Ich habe festgestellt, dass mein Code eine Protokollsperre hat. Bei dieser Protokollsperre stellte ich fest, dass in ArrayBlockingQueue.put ein Block vom Thread-Stapel vorhanden war. Weitere Untersuchungen ergaben, dass es sich um eine Blockierungswarteschlange mit einer Länge von 1024 handelte. Dies bedeutet, dass nachfolgende Put-Anforderungen blockiert werden, wenn sich 1024 Objekte in dieser Warteschlange befinden.

Der Programmierer, der diesen Code schrieb, schien zu denken, dass, wenn die BlockingQueue voll war, und dass Daten verarbeitet werden sollten. Der betreffende Code ist unten.

if (blockingQueue.retainCapacity() < 1) { //todo } blockingQueue.put

Das Problem besteht hier aus zwei Hauptteilen.

  1. Ein vollständiges Urteil geht direkt zu "setzen" statt zu "sonst".

  2. Die Verarbeitungslogik lautet // todo ..., auch wenn die Warteschlange voll ist.

Der obige Code zeigt, dass dieser spezielle Programmierer mit der BlockingQueue-Schnittstelle nicht vertraut ist. Sie müssen diese Entscheidung nicht zuerst treffen, um dieses Ergebnis zu erhalten. Ein besserer Weg wäre die Verwendung von blockingQueue.offer. Wenn dies als "falsch" zurückgegeben wird, können Sie die entsprechende Ausnahmebehandlung implementieren.

Typ Warteschlangen blockieren

BlockingQueue ist eine häufig verwendete Datenstruktur im Produktions- / Verbrauchermodus. Die am häufigsten verwendeten Typen sind ArrayBlockingQueue, LinkedBlockingQueue und SynchronousQueue.

Der Hauptunterschied zwischen ArrayBlockingQueue und LinkedBlockingQueue sind die Objekte, die in die Warteschlange gestellt werden. Einer wird für Arrays und der andere für verknüpfte Tabellen verwendet. Andere Unterschiede werden auch in den Code-Hinweisen erwähnt.

Verknüpfte Warteschlangen haben normalerweise einen höheren Durchsatz als Array-basierte Warteschlangen, weisen jedoch für die meisten gleichzeitigen Anwendungen eine schlechte vorhersagbare Leistung auf.

SynchronousQueue ist eine spezielle BlockingQueue. Es wird während des Angebots verwendet. Wenn derzeit kein anderer Thread aufgenommen oder abgefragt wird, schlägt das Angebot fehl. Es schlägt auch fehl, wenn während des Take kein anderer Thread gleichzeitig das Angebot ausführt. Dieser spezielle Modus eignet sich für Threads aus Warteschlangen und nicht festen Thread-Pools mit hohen Antwortanforderungen.

Problemübersicht

Online-Geschäftsszenarien erfordern einen Timeout-Mechanismus in allen Bereichen, in denen Parallelität und externer Zugriff blockiert sind. Ich weiß nicht, wie oft ich das Fehlen eines Timeout-Mechanismus als Ursache für ein großes Hindernis für das Online-Geschäft gesehen habe. Das Online-Geschäft konzentriert sich auf die schnelle Bearbeitung und Bearbeitung von Anfragen. Ein schneller Ausfall ist daher das wichtigste Prinzip beim Entwurf von Online-Geschäftssystemen und der Code-Programmierung. Nach diesem Prinzip besteht der offensichtlichste Fehler im obigen Code darin, Put anstelle von Offer zu verwenden, wobei der Timeout-Mechanismus verwendet wird. Alternativ sollte in unkritischen Szenarien das Angebot direkt verwendet werden, und das Ergebnis von "Falsch" kann dazu führen, dass direkte Ausnahmen ausgelöst oder protokolliert werden.

Für BlockingQueue-Szenarien müssen Sie zusätzlich zum Timeout-Mechanismus die Warteschlangenlänge begrenzen. Andernfalls wird standardmäßig Integer. MAX_VALUE verwendet. In diesem Fall führt ein Fehler im Code dazu, dass der Speicher gestoppt wird.

Wenn wir über BlockingQueue sprechen, erwähnen wir auch den am häufigsten verwendeten Bereich von BlockingQueue, den Thread-Pool.

ThreadPoolExecutor verfügt über einen BlockingQueue-Parameter. Wenn hier ArrayBlockingQueue oder LinkedBlockingQueue verwendet wird und sich coreSize und poolSize des Thread-Pools unterscheiden, bietet der Threadpool zuerst die BlockingQueue an, nachdem der coreSize-Thread belegt ist. Wird gesendet werden. Bei Erfolg endet der Prozess. Dieses Szenario entspricht jedoch nicht immer den Anforderungen des Online-Geschäfts.

Online-Unternehmen arbeiten in einer schnelllebigen Umgebung und erfordern eine schnelle Verarbeitung, anstatt Anforderungen in Warteschlangen zu stellen. Tatsächlich ist es für das Online-Geschäft am besten, wenn die Anforderungen überhaupt nicht in die Warteschlange gestellt werden. Diese Art von Online-Geschäftsstruktur kann leicht zerstört werden. Dies ist eine relativ einfache, aber gute Möglichkeit, Anforderungen, die die Kapazität des Systems überschreiten, direkt abzulehnen und stattdessen eine Fehlermeldung auszugeben. .. Aber es ist ein begrenzter Mechanismus.

Beachten Sie beim Schreiben von sehr gleichzeitigem und verteiltem Code, dass nicht nur das Systemdesign, sondern auch die Details des Codes beachtet werden müssen. Auf diese Weise können Sie die oben genannten Probleme vermeiden.

Recommended Posts

So lösen Sie die Probleme, die durch die drei Blockierungswarteschlangen von Java verursacht werden
So bestimmen Sie die Anzahl der Parallelen
So sortieren Sie eine Liste von SelectItems
So geben Sie die Summe von drei beliebigen Zahlen ohne denselben Wert aus
So lösen Sie die lokale Umgebungskonstruktion von Ruby on Rails (MAC)!
[Rails] So lösen Sie die Zeitverzögerung von created_at nach der Speichermethode
So finden Sie die Ursache des Ruby-Fehlers
Passen Sie an, wie der Inhalt von Recyclerview aufgeteilt wird
Wie komme ich zum heutigen Tag?
Ausgabe der Verwendung der Slice-Methode
So zeigen Sie das Ergebnis des Ausfüllens des Formulars an
[Java] So erhalten Sie die URL der Übergangsquelle
Wie schreibe ich Scala aus der Perspektive von Java
[Java] So erhalten Sie den Maximalwert von HashMap
[Rails] So ändern Sie den Spaltennamen der Tabelle
[Android] So erhalten Sie die Einstellungssprache des Terminals
[Rails] So erhalten Sie den Inhalt starker Parameter
So beurteilen Sie den Klick eines beliebigen Bildbereichs
So laden Sie eine ältere Version von Apache Tomcat herunter
[Swift] So erhalten Sie die Firebase-Dokument-ID
So legen Sie ein Wiederholungslimit für Sidekiq fest und benachrichtigen tote Warteschlangen mit Slack
So zeigen Sie das Auswahlfeld von time_select alle 30 Minuten an
So erhalten Sie die längsten Informationen von Twitter ab dem 12.12.2016
[Ruby] So rufen Sie den Inhalt des Doppel-Hash ab
Hinzufügen von Elementen ohne Angabe der Länge des Arrays
Medianwert von drei Werten
[Rails] So zeigen Sie eine Liste der Beiträge nach Kategorie an
Wie man einige Methoden der zu testenden Klasse verspottet
So leiten Sie den letzten Tag des Monats in Java ab
So ändern Sie den Inhalt der JAR-Datei, ohne sie zu dekomprimieren
So überprüfen Sie die Erweiterung und Größe der hochgeladenen Dateien
[jsoup] So erhalten Sie die gesamte Dokumentation
Ich habe versucht, das Problem der "mehrstufigen Auswahl" mit Ruby zu lösen
[Swift] So ändern Sie dynamisch die Höhe der Symbolleiste auf der Tastatur
[Rails] So erhalten Sie die URL der Übergangsquelle und leiten sie um
[Swift5] So erhalten Sie ein Array und eine Reihe von Unterschieden zwischen Arrays
So legen Sie die IP-Adresse und den Hostnamen von CentOS8 fest
So zeigen Sie 0 auf der linken Seite des Standardeingabewerts an
[Tipps] So lösen Sie Probleme mit XCode und Swift für Anfänger
[Rails / Heroku / MySQL] So setzen Sie die Datenbank der Rails-App auf Heroku zurück
So erhalten Sie den Inhalt von Map mithilfe des for-Anweisungsmemorandums
[Rails] So lassen Sie die Anzeige der Zeichenfolge der link_to-Methode weg
[Schienen] So ändern Sie den Seitentitel des Browsers für jede Seite
So erhalten Sie die ID des automatisch inkrementierten PRIMAY-Schlüssels in MyBatis
So beheben Sie den unbekannten Fehler, der bei der Verwendung von slf4j in Java aufgetreten ist
[chown] So ändern Sie den Eigentümer einer Datei oder eines Verzeichnisses
So überprüfen Sie den Inhalt der Java-Zeichenfolge mit fester Länge
So ermitteln Sie die Länge einer Audiodatei mit Java
Drei Gründe für Frustration vor der Veröffentlichung von Web Services
Ich habe versucht, das Problem des Google Tech Dev Guide zu lösen
So erhöhen Sie den Wert von Map in einer Zeile in Java
Verwendung der link_to-Methode
Verwendung der include? -Methode
Verwendung der Methode form_with