Mindmap-Galerie Aufstiegspfad für Java-Architekten P5-P7 mit einem Jahresgehalt von 500.000-700.000
Java-Architekt P5-P7-Aufstiegspfad mit einem Jahresgehalt von 500.000 bis 700.000, praktischer Datenstruktur und Algorithmus, Datenstrukturmodell für Microservice-Lösungen, praktischer Leistungsoptimierung der virtuellen JVM-Maschine. Gleichzeitige Programmierpraxis, Interpretation des Quellcodes des Microservice-Frameworks, Interpretation des Quellcodes des Sammlungsframeworks, verteilte Architekturlösungen. Design und tatsächliche Implementierung der Internet-Architektur für verteilte Transaktionen, Prinzipien der verteilten Nachrichten-Middleware, tatsächliche Leistungsoptimierung von MySQL und detaillierte Interpretation des Netty-Quellcodes.
Bearbeitet um 2023-11-21 16:53:38Einhundert Jahre Einsamkeit ist das Meisterwerk von Gabriel Garcia Marquez. Die Lektüre dieses Buches beginnt mit der Klärung der Beziehungen zwischen den Figuren. Im Mittelpunkt steht die Familie Buendía, deren Wohlstand und Niedergang, interne Beziehungen und politische Kämpfe, Selbstvermischung und Wiedergeburt im Laufe von hundert Jahren erzählt werden.
Einhundert Jahre Einsamkeit ist das Meisterwerk von Gabriel Garcia Marquez. Die Lektüre dieses Buches beginnt mit der Klärung der Beziehungen zwischen den Figuren. Im Mittelpunkt steht die Familie Buendía, deren Wohlstand und Niedergang, interne Beziehungen und politische Kämpfe, Selbstvermischung und Wiedergeburt im Laufe von hundert Jahren erzählt werden.
Projektmanagement ist der Prozess der Anwendung von Fachwissen, Fähigkeiten, Werkzeugen und Methoden auf die Projektaktivitäten, so dass das Projekt die festgelegten Anforderungen und Erwartungen im Rahmen der begrenzten Ressourcen erreichen oder übertreffen kann. Dieses Diagramm bietet einen umfassenden Überblick über die 8 Komponenten des Projektmanagementprozesses und kann als generische Vorlage verwendet werden.
Einhundert Jahre Einsamkeit ist das Meisterwerk von Gabriel Garcia Marquez. Die Lektüre dieses Buches beginnt mit der Klärung der Beziehungen zwischen den Figuren. Im Mittelpunkt steht die Familie Buendía, deren Wohlstand und Niedergang, interne Beziehungen und politische Kämpfe, Selbstvermischung und Wiedergeburt im Laufe von hundert Jahren erzählt werden.
Einhundert Jahre Einsamkeit ist das Meisterwerk von Gabriel Garcia Marquez. Die Lektüre dieses Buches beginnt mit der Klärung der Beziehungen zwischen den Figuren. Im Mittelpunkt steht die Familie Buendía, deren Wohlstand und Niedergang, interne Beziehungen und politische Kämpfe, Selbstvermischung und Wiedergeburt im Laufe von hundert Jahren erzählt werden.
Projektmanagement ist der Prozess der Anwendung von Fachwissen, Fähigkeiten, Werkzeugen und Methoden auf die Projektaktivitäten, so dass das Projekt die festgelegten Anforderungen und Erwartungen im Rahmen der begrenzten Ressourcen erreichen oder übertreffen kann. Dieses Diagramm bietet einen umfassenden Überblick über die 8 Komponenten des Projektmanagementprozesses und kann als generische Vorlage verwendet werden.
Der Weg zum Aufstieg als JAVA-Architekt
Datenstruktur und Algorithmenpraxis
Überprüfung der Mathematikkenntnisse
Index
Logarithmus
Serie
Modulo-Arithmetik
Die Komplexität
Zeitkomplexität
Raumkomplexität
Datenstruktur
Stapelmodell
First-in-Last-out-Prinzip
Pop/Push
Stack-Anwendung
Warteschlangenmodell
First-In-First-Out-Prinzip
sequentielle Warteschlange
verkettete Warteschlange
deque
Prioritätswarteschlange
Baummodell
Binärbaum
AVL-Baum
Hinweis Binärbaum
roter schwarzer Baum
sich ausbreitender Baum
Hash-Modell
Hash-Funktion
Lineare Erkennungsmethode
Quadraterkennungsmethode
doppelter Hash
Hash-Funktionsmethode
direkte Adressierungsmethode
digitale Analyse
Quadrat-Medium-Methode
Faltmethode
Division mit Restrestverfahren
Zufallszahlenmethode
Wie man mit Konflikten umgeht
Lineares Sondieren und anschließendes Hashing
Squared Probing und Hashing
Heap-Modell
Linker Stapel
schiefer Stapel
Algorithmenpraxis
Sortieralgorithmus
Sortieren durch Einfügen
Hill-Sorte
Heap-Sortierung
Zusammenführen, sortieren
Schnelle Sorte
Blasensortierung
Praktischer Algorithmus
Gieriger Algorithmus
Huffman-Codierung
Ungefähres Problem beim Packen von Behältern
Teilen-und-Herrsche-Algorithmus
Laufzeit des Divide and Conquer-Algorithmus
Aktuelle Ausgaben
Wähle eine Frage aus
dynamische Programmierung
Verwenden Sie eine Tabelle anstelle einer Rekursion
Die Reihenfolge der Matrixmultiplikation
optimaler binärer Suchbaum
Der kürzeste Weg für alle Punktpaare
Randomisierungsalgorithmus
Zufallszahlengenerator
Sprungtisch
Eignungsprüfung
Datenstrukturmodell der Microservice-Lösung
Cluster-Algorithmus des Registrierungscenters
Nacos-Clusterwahl-Raft-Algorithmus
Epidemie-Ausbreitungsalgorithmus P2P-Gossip-Protokoll
Eureka-Nachrichtenübertragungskonsistenzprotokoll
Distributed Transaction Consistency Protocol
Starkes Konsistenzprotokoll
Schwaches Konsistenzprotokoll
Eventualkonsistenzprotokoll
Zookeeper-Konsensprotokollalgorithmus
ZAB Atomic Broadcast Protocol
Paxos-Konsensprotokoll
Algorithmus zur verteilten Cache-Eliminierung
LRU-Cache-Räumungsalgorithmus (weniger kürzlich verwendet).
LFU-Cache-Räumungsalgorithmus (Least Frequently Used Algorithm).
ARC-Cache-Eliminierungsalgorithmus (Adaptive Cache Replacement Algorithm).
FIFO-Cache-Räumungsalgorithmus (First In, First Out).
MRU-Cache-Räumungsalgorithmus (zuletzt verwendet).
Verteiltes Cache-Aufschlüsselungsprotokoll
Blütenfilter
Kuckucksfilter
Lastausgleichsalgorithmus
Algorithmus des Abfragemechanismus
Zufallsalgorithmus
Fester IP-Algorithmus
Gewichtsalgorithmus
Microservice-Strombegrenzungsalgorithmus
Zähleralgorithmus (festes Fenster).
Schiebefenster-Algorithmus
Leaky-Bucket-Algorithmus
Token-Bucket-Algorithmus
Algorithmus zur verteilten Rechenaufgabenplanung (xxl-job)
Rotationsmethode
Gewichtungsmethode
Hashing
Least-Join-Methode
Methode des minimalen Fehlens
schnellste Antwortmethode
genetischen Algorithmus
Lösung für den Ameisenkolonie-Algorithmus
Verteiltes Datensynchronisations- und Konsistenzprotokoll
MySQL
halbsynchrone Replikation
Asynchrone Replikation
Globale Synchronisierung
Zwischenspeicher
Kanal
Otter
(openresty/tengine) Tatsächlich hohe Parallelität
Natives Nginx-Kernmodul
Nginx-Modultypen
Standard-HTTP-Modul
Optionales HTTP-Modul
Drittanbietermodul (Lua)
Nginx-ereignisgesteuertes Modell und Funktionen
Nginx-Kernkonfiguration
Konfiguration des virtuellen Hosts
stromaufwärts
Standort
Statische Verzeichniskonfiguration
Konfiguration des https-Protokolls
Konfiguration des Nginx-Lastausgleichsalgorithmus
Algorithmus des Abfragemechanismus
Zufallsalgorithmus
Fester IP-Algorithmus
Gewichtsalgorithmus
openresty/tengine
Openresty kombiniert mit Lua, um Produktdetailseiten auf Milliardenebene zu realisieren
Tengine ist ein von Alibaba entwickeltes Webserverprojekt
Praktische Leistungsoptimierung der virtuellen JVM-Maschine
Entwicklungsgeschichte der Programmiersprache
Assemblersprache/Maschinensprache
C/C-Sprache
java/php/easy language/ython
JVM-KlassenladerClassLoader
Analyse des Klassenlader-Implementierungsprinzips aus dem Quellcode der HotSpot Virtual Machine (C).
Was ist ein Klassenlader?
Lesen Sie unsere Klassendatei in den Speicher
Klassifizierung von Klassenladern
Bootstrap-Klassenlader (in C geschrieben)
$JAVA_HOME/jre/lib
Erweiterungsklassenlader (in Java geschrieben)
JAVA_HOME/jre/lib/ext
(Anwendung) AppClassLoader-Klassenlader (in Java geschrieben)
Klassen- und JAR-Pakete unter Classpath
Benutzerdefinierter Klassenlader (in Java geschrieben)
Benutzerdefiniertes Klassendateiverzeichnis
Vorteile des elterlichen Delegationsmechanismus
Der Zweck besteht darin, Konflikte zwischen den von Entwicklern definierten Klassen und den von JDK definierten Quellcodeklassen zu verhindern und die Eindeutigkeit der Klasse im Speicher sicherzustellen.
Prinzip der übergeordneten Klassenlader-Delegierung und wie man es durchbricht
Spi-Mechanismus
Detaillierte Quellcode-Analyse des Startup-Klassen-/Erweiterungs-/Anwendungsklassenladers
Prinzip der Java SPIService Provider-Schnittstelle
Implementierungsprinzip des Tomcat/Jetty-Klassenladers
So passen Sie einen Klassenlader an, um Bytecode und handgeschriebene Hot-Deployment-Plug-Ins zu laden
Lokale Festplatte
Netzwerkakquise
Datenbank
Dynamische Proxy-Generierung
Krieg/Glas
Analyse der JVM-Speicherstrukturprinzipien
JVM-Laufzeitzone
Programm zähler
Notieren Sie die Zeilennummer des aktuellen Thread-Ausführungscodes, um den nächsten CPU-Kontextwechsel zur Wiederaufnahme der Ausführung zu erleichtern.
Haufen
Neue Objekte werden im Heap gespeichert (von Threads gemeinsam genutzt)
Fehlerbehebung bei Heap-Speicherlecks in der Produktionsumgebung
Speicherleck
Was ist ein Heap-Speicherverlust?
Heap-Speicheranwendungsraum, GC kann den Speicher nicht freigeben
Szenarien, in denen Speicherlecks auftreten
Threadlokaler Speicherverlust
Speicherleck für benutzerdefiniertes HashMap-Schlüsselobjekt
Fehlerbehebung bei Heap-Speicherlecks in der Produktionsumgebung
Jps/Jmap
Jvisualvm/jconsole
Speicherüberlauf
Was ist ein Heap-Speicherüberlauf?
Bei der Beantragung von Speicherplatz im Heap-Speicher ist nicht genügend Speicherplatz vorhanden.
Heap-Speicherüberlauf
Die in den Speicher geladene Datenmenge ist zu groß, z. B. weil zu viele Daten gleichzeitig aus der Datenbank abgerufen werden
Es gibt einen Verweis auf das Objekt in der Sammlungsklasse, der nach der Verwendung nicht gelöscht wird, sodass die JVM ihn nicht recyceln kann.
Der Code enthält eine Endlosschleife oder die Schleife generiert zu viele doppelte Objektentitäten.
Der Startparameter-Speicherwert legt den Heap-Speicher zu klein fest.
Lösung für Speicherüberlauf
Erhöhen Sie den Heap-Speicher
Details zur Heap-Speicherstruktur
Aufteilung der Heap-Struktur
Neue Generation/Alte Generation
neue Generation
Das neu erstellte Objekt wird in der neuen Generation gespeichert
hohes Alter
Häufig verwendete Objekte werden in der alten Generation gespeichert
JDK-Version
jdk1.7
Eden (Garten Eden) von (s0) bis (s1) permanente Generation (Methodenbereich)
jdk1.8
Eden (Garten Eden) von (s0) bis (s1) permanente Generation (Metaraum)
charakteristisch:
Das Standardverhältnis zwischen der neuen Generation und der alten Generation beträgt 1:2
-XX:NewRatio
Standard-Eden mit s0/s1 8:1:1
-XX:SurvivorRatio
gebräuchliche Worte
YoungGen (neue Generation)
oldGen (alte Generation)
s0(von)
s1(zu)
PermGen (permanente Generation)
Metaraum
Klassifizierung von GC
Teilsammlung
Sammlung der neuen Generation (Minor GC/Young GC)
Sammlung der alten Generation (Major GC/Old GC)
CMS GC sammelt die alte Generation separat.
Sammlung von Heap- und Methodenbereichen
(Vollständiger GC): Sammeln Sie die Garbage Collection des gesamten Java-Heap- und Methodenbereichs (Metaraum).
Häufige Fragen im Vorstellungsgespräch
Der Unterschied zwischen vollständigem GC und Minor GC/Young GC
Vollständiger GC löst die Sammlung der neuen und alten Generation aus
Minor GC löst die GC-Sammlung der neuen Generation aus
Kleinere GC-Sammelzeiten sind sehr häufig
Full GC löst das Recycling aus, wenn im alten Generations- oder Methodenbereich (Metaspace) nicht genügend Speicher vorhanden ist.
Die GC-Rückgewinnungseffizienz der vollständigen GC ist sehr gering
Versuchen Sie, kein vollständiges GC-Recycling auszulösen
Wo werden große Gegenstände gelagert?
Wenn der Eden-Bereich nicht gespeichert werden kann, wird er direkt in der alten Generation gespeichert.
Analyse von GC-Protokollen
Erinnerungsflucht
Platzgarantie
Analyse der internen Struktur von Thread-Stapel und Stapelrahmen
lokale Variablentabelle
Operandenstapel
dynamische Verbindung
Methodenexport
Technologie des lokalen Methodenstapels (JNI ruft C-Code auf).
String-Konstantenpool
Konstante Poolklassifizierung
statischer konstanter Pool
Führen Sie einen konstanten Pool aus
String-Konstantenpool
Konstanter Pool für verschiedene Speicherbereiche der JDK-Version
Der String-Konstantenpool in JDK1.6 und früher wird im Methodenbereich gespeichert (permanente Generierung).
In JDK1.7 beginnt der String-Konstantenpool im Heap gespeichert zu werden
Der String-Konstantenpool in JDK1.8 wird im Heap gespeichert
Häufige Fragen zu String-Interviews
Warum hat JDK1.7 begonnen, den String-Konstantenpool im Heap zu speichern?
In JDK7 wird der String-Konstantenpool im Heap-Bereich platziert. Da die Recyclingeffizienz der permanenten Generation sehr gering ist, wird die Speicherbereinigung der permanenten Generation nur während der vollständigen GC ausgeführt, und die vollständige GC wird ausgelöst, wenn in der alten Generation nicht genügend Speicherplatz vorhanden ist und die permanente Generation nicht ausreicht .
Dies führt zu einer geringen Recyclingeffizienz des String-Konstantenpools. In unserer Entwicklung wird eine große Anzahl von Strings erstellt und die Recyclingeffizienz ist gering, was zu einem unzureichenden permanenten Generierungsspeicher führt. Wenn Sie es auf den Heap legen, kann der Speicher rechtzeitig zurückgewonnen werden.
String s1 = „mayikt“;
String s1 = „mayikt“; s1 zeigt auf den String-Konstantenpool
neuer String("mayikt");
Erstellen Sie eine Heap-Space-Adresse im Heap und geben Sie sie an s2 zurück s2 erhält die Heap-Speicheradresse und Mayikt führt den String-Konstantenpool in der String-Klasse ein.
JVM-Objektspeicherlayout
Objektlayout
Objektheader
Instanzdaten
Polsterung ausrichten
Wie viele Bytes belegt ein neues Objekt?
Objektzugriffsort
Griffmodus
Ein Teil des Speichers kann als Handle-Pool in den Java-Heap unterteilt werden. Was in der Referenz in der lokalen Variablen gespeichert ist, ist die Handle-Adresse des Objekts.
direkte Zeigermethode
Was als Referenz gespeichert wird, ist direkt die Objektadresse.
Wie Objekte entstehen
1. neues Objekt
2. Erstellen Sie Objekte mithilfe von Reflexion
3. Verwenden Sie clone(), um das Objekt zu klonen
4. Deserialisierte Objekte verwenden
5. Die Bibliothek Objenesls eines Drittanbieters erstellt Objekte
Objektdetails erstellen
1. Überprüfen Sie, ob die Klasse des Objekts geladen, analysiert und initialisiert wurde
1. Wenn die Java Virtual Machine auf eine neue Bytecode-Anweisung stößt, prüft sie zunächst, ob die Parameter dieser Anweisung die symbolische Referenz der Klasse im Konstantenpool (im Metaspace) finden können, und prüft dann die durch diese symbolische Referenz dargestellte Klasse. Ob sie geladen, analysiert und initialisiert wurde (um festzustellen, ob die Klasse vom Metaspace geladen wurde)
Wenn nicht, muss zuerst der entsprechende Klassenladevorgang ausgeführt werden (verwenden Sie dann den übergeordneten Delegierungsmechanismus, um die Klasse zu finden (vollständiger Pfad der Klasse). Wenn sie nicht gefunden wird, wird ein Fehler gemeldet: ClassNotFoundException).
2. Nachdem die Klassenladeprüfung bestanden wurde, weist die virtuelle Maschine Speicher für das neue Objekt zu.
Verwenden Sie diese Option, wenn der Heap-Speicher regelmäßig ist
Zeigerkollision
Verwenden Sie diese Option, wenn der Heap-Speicher unregelmäßig ist
kostenlose Liste
3. Die Objekterstellung ist ein sehr häufiges Verhalten in einer virtuellen Maschine. Auch wenn Sie nur die Position ändern, auf die ein Zeiger zeigt, ist sie unter gleichzeitigen Umständen nicht threadsicher.
1. Verwenden Sie die CAS-Fehlerwiederholung, um die Atomizität der Aktualisierungen sicherzustellen.
2. Weisen Sie jedem Thread ein Stück TLAB-Speicherplatz zu, der eindeutig für den aktuellen Thread in Eden (Eden Campus) ist.
4. Nachdem die Speicherzuweisung abgeschlossen ist, muss die virtuelle Maschine den zugewiesenen Speicherplatz (jedoch nicht den Objektheader) auf Null initialisieren. Wenn TLAB verwendet wird, kann diese Arbeit auch im Voraus zugewiesen werden Übrigens zu TLAB. Dieser Schritt stellt sicher, dass die Instanzfelder des Objekts ohne Zuweisung von Anfangswerten direkt im Java-Code verwendet werden können, sodass das Programm auf die Nullwerte zugreifen kann, die den Datentypen dieser Felder entsprechen.
5. Legen Sie die Objekt-Header-Informationen fest. Die Java Virtual Machine muss außerdem die erforderlichen Einstellungen für das Objekt vornehmen, z. B. von welcher Klasse das Objekt eine Instanz ist, wie die Metadateninformationen der Klasse gefunden werden und der Hash-Code des Objekts (Tatsächlich wird der Hash-Code des Objekts verzögert, bis die Methode Object::hashCode() tatsächlich aufgerufen wird), das GC-Generierungsalter des Objekts und andere Informationen. Diese Informationen werden im Objektheader (Object Header) des Objekts gespeichert. Abhängig vom aktuellen Betriebsstatus der virtuellen Maschine, z. B. ob die Bias-Sperre aktiviert ist usw., wird der Objektheader auf unterschiedliche Weise festgelegt.
6. Führen Sie die Init-Methode zur Initialisierung aus
JVM-Garbage-Collection-Algorithmus
Garbage-Collection-Algorithmus
Mark-and-Sweep-Algorithmus
Vorteile: hohe Effizienz/keine Verschiebung von Speicheradressen
Nachteile: anfällig für Fragmentierung
Tag-Sortieralgorithmus
Vorteile: vermeidet Fragmentierungsprobleme
Nachteile: Verschieben der Speicheradresse, geringe Effizienz
Markierter Kopieralgorithmus
Vorteile: vermeidet Fragmentierungsprobleme
Nachteile: Verschieben der Speicheradresse, hohe Effizienz
Prinzip des Generationsalgorithmus
neue Generation
hohes Alter
JDK1.0-14 Kollektor
Müllsammler-Kombination
(Parallel in der neuen Generation) ParNew (seriell in der alten Generation) Serial alt
(Seriennummer der neuen Generation) Seriell, (Alte Generation) Seriennummer alt
(Seriell der neuen Generation) Seriell/CMS (Parallelität der alten Generation)
(JDK9 veraltet)
(Parallelität in der neuen Generation) ParNew/CMS (Parallelität in der alten Generation)
(Nicht empfohlen für JDK9)
(Parallel der neuen Generation) Parallel/SeriellOld (Seriell der alten Generation)
Nicht empfohlen
(Parallel in der neuen Generation) Parallel Scavenge/Parallel Old (parallel in der alten Generation)
JDK8-Standard
G1 (JDK9-Standard) gesamte Heap-Sammlung
JDK8-Standard
Seriell (einzelnes GC-Thread-Recycling)
Ausführliche Erklärung des seriellen Garbage Collectors
Kombination
(Seriell) markierter Replikationsalgorithmus der neuen Generation
Serieller Old-Mark-Komprimierungsalgorithmus
Anwendungsszenarien
Verwenden Sie eine Single-Core-CPU und kleinen Speicher
Parallel (Recycling mehrerer GC-Threads)
Detaillierte Erklärung des ParNew Garbage Collectors
Anwendungsszenarien
neue Generation
Geeignet für Multicore-CPUs
Kombination
(Alte Generation) Seriell alt (Markierungskomprimierungsalgorithmus)
(Alte Generation) CMS (Mark-and-Sweep-Algorithmus)
Detaillierte Erläuterung des parallelen Garbage Collectors
Anwendungsszenarien
Mehrere GC-Sammlungen der neuen/alten Generation gleichzeitig
Kombination
Parallel
Parallel oldGC
Parallelität (GC- und Benutzer-Threads werden gleichzeitig ausgeführt)
CMS-Garbage-Collector-Prinzip (wichtige Punkte)
Umsetzungsprinzip
Anfangsnote
gleichzeitige Markierung
umbenennen
Gleichzeitig klar
Was sind die Mängel des CMS-Kollektors?
Der Mark-and-Sweep-Algorithmus verursacht Fragmentierungsprobleme
Alternative SerialOld ist ineffizient
Lösen Sie das Problem fehlender Beschriftungen basierend auf der inkrementellen Aktualisierungsmethode
G1-Kollektorprinzip (wichtige Punkte)
Umsetzungsprinzip
n mehrere verschiedene Regionen
Regionsspeichersatz (Remember Set)
Ausführliche Erklärung von Cardtable
Lösen Sie das Gebäudemarkierungsproblem basierend auf dem Original-Schnappschuss (SATB).
Detaillierte Erklärung des ZGC-Garbage Collectors
Ausführliche Erklärung der Garbage Collectors Epsilon und Shenandoah
Garbage-Copy-Algorithmus
Prinzip des dreifarbigen Markierungsalgorithmus des Garbage-Collection-Mechanismus
Mehrere Etikettierungs-/fehlende Etikettierungsprobleme, verursacht durch den dreifarbigen Markierungsalgorithmus
schwimmender Müll
Problem mit fehlendem Gebot
Lösung für fehlendes Objektetikett
Basierend auf der inkrementellen Update-Methode (CMS)
Basierend auf der ursprünglichen Snapshot-Methode satb(G1)
Detaillierte Erläuterung des Regionsspeichersatzes (Remember Set) und der Kartentabelle (Cardtable)
stopp die Welt
Warum tritt das Stop-the-World-Problem auf?
Wie man das Stop-the-World-Problem vermeidet
Detaillierte Erläuterung der JVM-Tuning-Tools
Detaillierte Erläuterung der JDK-eigenen Optimierungsbefehle Jstat, Jinfo, Jmap, Jhat und Jstack
Detaillierte Erläuterung der Tuning-Tools Jvisualvm und Jconsole
Detaillierte Erklärung der Verwendung des Alibaba-Tools Arthas
GC-Protokollanalysetool
So lesen Sie GC-Protokolldetails
Verwendung des Protokollanalysetools GCEasy
Verwendung des Protokollanalysetools GCViewer
Praxis der JVM-Parameteroptimierung
100-Millionen-Level-Verkehrsprojekt-Heap-Speicher, Garbage-Collection-Parameter der jungen Generation und der alten Generation, Einstellung und Optimierung
Online-Produktionsumgebung OMM-Speicherüberlaufüberwachungstool und Positionierungslösung
Optimierungspraktiken zur Reduzierung schwerwiegender vollständiger GC in Online-Produktionsumgebungen, die zu direkten Systemabstürzen führen
System mit hoher Parallelität, wie man häufige GC-Vorgänge in Online-Produktionsumgebungen vermeidet
System mit hoher Parallelität, wie man den G1/CMS-Kollektor optimiert
So legen Sie die anfängliche Speichergröße des JVM-Heaps für den durchschnittlichen täglichen Millionen-PV-Dienst fest
Gleichzeitige Programmierung in der Praxis
Grundlagen des Betriebssystems
Umschaltvorgang zwischen Benutzermodus und Kernelmodus
Linux-Prozessmodellverwaltung
Prinzip der prozessübergreifenden Kommunikation unter Linux
Prinzipien der Linux-Netzwerkkommunikation
Multithreading-Grundlagen
Schnellstart mit Multithreading
Was ist ein Prozess/Thread?
Der Prozess ist die kleinste Einheit der Ressourcenzuweisung
Thread ist die kleinste Einheit der Programmausführung
Multithread-Anwendungsszenarien
Client-Entwicklung (mobile App/).
SMS/E-Mail asynchron senden
Ändern Sie Code, dessen Ausführung einige Zeit in Anspruch nimmt, in eine asynchrone Ausführung mit mehreren Threads.
Protokoll asynchron schreiben
Multithread-Download
Unterschied zwischen Multithreading und Single-Threading
Multithreading (parallele Ausführung)
Einzelner Thread (synchrone Ausführung)
Wie man das Konzept des Multithread-CPU-Switching versteht
Die aktuelle CPU schaltet um, um einen anderen Thread auszuführen
Stimmt es, dass es umso besser ist, je mehr Multithreading aktiviert ist?
Nicht unbedingt kann das Öffnen zu vieler Threads leicht zu einem CPU-Kontextwechsel führen.
Der Unterschied zwischen Benutzer-Threads und Daemon-Threads
So stoppen Sie einen Thread ordnungsgemäß
Analyse von sieben Multithreading-Zuständen
Ausgangszustand
Bereitschaftszustand
Betriebsstatus
<font face="宋体"><span style="font-size: 14px;">Todeszustand</span></font><br>
Sperrzustand
Timeout warten
Wartezustand
Fünf Möglichkeiten, Multithreading zu erstellen
Erben Sie die Thread-Klasse, um einen Thread zu erstellen
Implementieren Sie die Runnable-Schnittstelle, um einen Thread zu erstellen
Erstellen Sie Threads mit Callable und Future
Verwenden Sie einen Thread-Pool wie das Executor-Framework
Erstellen Sie einen Thread mit der asynchronen Annotation @Async
Erstellen Sie einen Thread mit dem Lambda-Ausdruck
Multithread-Thread-Sicherheit
Was ist ein Thread-Sicherheitsproblem?
Wenn mehrere Threads gleichzeitig in dieselbe globale Variable schreiben, können sie durch andere<br>Threads gestört werden, was zu Thread-Sicherheitsproblemen führen kann.
Der Unterschied zwischen Sperre und synchronisierter Sperre
lock Manuelles Erfassen und Freigeben von Sperren
Synchronized erwirbt und gibt Sperren automatisch frei
SynchronizedJDK6 startet den automatischen Sperraktualisierungsprozess
Die zugrunde liegende Implementierung der Sperre basiert auf der aqs-Sperre und erfordert ein manuelles Upgrade der Sperre.
Multithread-Deadlock-Problem
So beheben Sie Deadlocks mit Multithreading
jconsole.exe diagnostiziert einen Deadlock
Ursachen für Multithread-Deadlock-Threads
Verschachtelte Synchronisierung innerhalb der Synchronisierung
So lösen Sie Thread-Sicherheitsprobleme (so stellen Sie die Thread-Synchronisierung sicher)
Synchronized löst Thread-Sicherheitsprobleme
Der synchronisierte Synchronisationscode ist schnell
Synchronisierte geänderte Instanzmethode
synchronisierte modifizierte statische Methode
Lock Lock löst Thread-Sicherheitsprobleme
Kommunikation zwischen mehreren Threads
abwarten und benachrichtigen
wait gibt die aktuelle Sperre frei und blockiert den aktuellen Thread
notify weckt den blockierten Thread
Das Prinzip der Join-Methode
Die unterste Ebene basiert auf der Wartekapselung
Synchronprinzip
Wie ein Objekt zusammengesetzt ist
Objektheader
Wort markieren
Hash-Code (HashCode), Alter der GC-Generierung, Sperrstatus-Flag, vom Thread gehaltene Sperre, voreingenommene Thread-ID, voreingenommener Zeitstempel
Klassenzeiger<br>
Instanzdaten
Mitgliedereigenschaften
Polsterung ausrichten
Die Größe des Objekts muss ein ganzzahliges Vielfaches von 8 Byte sein. Wenn es kein ganzzahliges Vielfaches von 8 Byte ist, wird es ausgerichtet und aufgefüllt.
Synchronisierter Schloss-Upgrade-Prozess
Vorspannungssperre
Das Sperren und Entsperren erfordert keinen zusätzlichen Overhead. Sie sind nur für den Zugriff desselben Threads auf den synchronisierten Codeblock ohne zusätzlichen Overhead geeignet. Wenn mehrere Threads gleichzeitig konkurrieren, wird die Sperre aufgehoben.
Leichtes Schloss
Konkurrierende Threads werden nicht blockiert, was die Reaktionsgeschwindigkeit des Programms verbessert. Wenn der konkurrierende Thread für die Sperre nie erhalten wird, wird Spin verwendet, um CPU-Ressourcen zu verbrauchen. Dies eignet sich für Situationen, in denen synchronisierte Codeblöcke sehr schnell ausgeführt werden Rotation nach 7)
Gewichtssperre
Der Thread-Wettbewerb verwendet keinen Spin, verbraucht keine CPU-Ressourcen und eignet sich für die synchrone Codeausführung über einen relativ langen Zeitraum.
Analyse nach dem Prinzip des synchronisierten Schlosserweiterungsprozesses
Bias-Sperre(101)
1. Der aktuelle Thread erhält anhand des Markierungsworts im Objektheader, ob es sich um eine voreingenommene Sperre handelt. Wenn es sich um eine voreingenommene Sperre handelt, ermitteln Sie, ob die ID des Threads die aktuelle Thread-ID ist.
2. Wenn es mit der aktuellen Thread-ID übereinstimmt, wird die CAS-Operation nicht wiederholt ausgeführt, sondern direkt in unseren Synchronisationscodeblock eingegeben.
3. Wenn es nicht mit der aktuellen Thread-ID übereinstimmt, es sich um eine sperrenfreie Situation handelt und keine anderen Threads mit mir konkurrieren, verwenden Sie CAS direkt, um den Sperrstatus in Markword auf 101 zu ändern und auch die aktuelle Thread-ID zu speichern im Markwort.
4. Andere Threads beginnen mit dem Bias-Lock-Thread zu konkurrieren. Wenn die Anzahl der Bias-Lock-Aufhebungen 20 erreicht, leiten sie den Bias-Lock stapelweise direkt an den T2-Thread weiter (Hinweis: Es gibt keine anderen Threads, die mit t2 konkurrieren). Wenn die Anzahl der Aufhebungen der Bias-Sperre das 20- oder 40-fache erreicht, beginnt die Rückgängigmachung der Stapelverarbeitung später.
5. Um die voreingenommene Sperre aufzuheben, müssen wir unseren voreingenommenen Sperrthread an einem globalen sicheren Punkt stoppen, unser Markword in eine leichte Sperre ändern und den voreingenommenen Sperrthread aufwecken.
6. Hinweis: JDK15 deaktiviert standardmäßig die voreingenommene Sperrenoptimierung.
Leichtes Schloss (000)
1. Wenn mehrere Threads gleichzeitig um dieselbe Sperre konkurrieren, aktualisieren Sie die Lightweight-Sperre und verwenden Sie CAS (ändern Sie den Markword-Sperrstatus = 00, ersetzen Sie ihn durch Markword und speichern Sie den HashCode-Wert derzeit direkt in unserem Stapelrahmen). , Die Adresse des Sperrdatensatzes wird im Markword gespeichert
2. Wenn wir eine leichte Sperre verwenden, um die Sperre aufzuheben, wird der Inhalt des Markierungswortwerts wiederhergestellt
Schwergewicht (010) (C-Monitor)
1. Wenn unser Thread es mehrmals versucht hat und die Sperre immer noch nicht erhalten hat, wird die aktuelle Sperre auf eine Schwergewichtssperre hochgestuft.
2.2. Threads, die die Sperre nicht erhalten haben, werden in der EntryList-Sammlung des C-Monitor-Objekts gespeichert. Gleichzeitig werden die CPU-Ausführungsrechte direkt blockiert und freigegeben Die Sperre im späteren Zeitraum ist sehr hoch, da der CPU-Kontextwechsel vom Benutzermodus in den Kernel erfolgen und der Markword-Wert in unserem Objektheader in C Monitor geändert werden muss. Das Java-Objekt mit dem Speicheradressenzeiger ist mit C Monitor verknüpft.
C Monitor-Monitorschloss (Schwergewichtsschloss)
Monitor (Objekt-Schwergewichtssperre)
Rekursionen (Anzahl der Rekursionen/Anzahl der Wiedereintritte)
Eigentümer (zeichnet die Thread-ID auf, die derzeit die Sperre hält)
waitSet (Threads, die darauf warten, dass sich der Pool im Wartezustand befindet, werden zu _WaitSet hinzugefügt)
EntryList (Sperrpool: Threads, die auf den Sperrblockstatus warten, werden zur Liste hinzugefügt)
Wird die Sperre sofort erhalten, wenn der Thread im Wartepool aktiviert wird?
Nachdem der Thread im Wartepool aktiviert wurde, wird der Wartepool in den Sperrpool übertragen und in die Warteschlange gestellt, um erneut um die Sperre zu konkurrieren.
Vergröberung, Eliminierung und Leistungsoptimierung von Sperren
Aufrauen von Schlössern
Jeder Thread hält die Sperre so kurz wie möglich
Beseitigung von Sperren
Die Sperrenbeseitigung ist eine Methode zur Sperrenoptimierung, die auf Compilerebene erfolgt
Volatile-Keyword-Prinzip
Schlüsselworteigenschaften
Sorgen Sie für Sichtbarkeit
Nachbestellung deaktivieren
Keine Garantie für Atomizität
Java-Speichermodell
Analyse der CPU-Multicore-Hardwarearchitektur
jmm acht Synchronisierungsspezifikationen
Volatile Cache Coherence Protocol
Busschleuse
MESI-Protokoll
Das Problem des falschen Teilens
Grundkonzepte von Cache-Zeilen
Bankfüllplan
Warum müssen Sie Volatilität zur Neuordnung/Speichersperre/Double-Check-Sperre hinzufügen?
Der Unterschied zwischen synchronisiert und volatil
Warum Volatile keine Atomizität garantiert
Klassifizierung gleichzeitiger Sperren
pessimistische Sperre
optimistische Verriegelung
Spin-Lock
Wiedereintrittssperre
faires Schloss
unfaire Sperre
Interpretation des aqs-Quellcodes
Interpretation des LockSupport-Quellcodes
Interpretation des AbstractQueuedSynchronizer-Quellcodes
ReentrantLock/ReentrantReadWriteLock, Interpretation des ReadWriteLock-Quellcodes
Interpretation des Semaphore/CountDownLatch/CyclicBarrie-Quellcodes
So implementieren Sie die unterste Ebene von AQS
A.Cas gewährleistet die Thread-Sicherheit von AQS
B. Eine doppelt verknüpfte Liste speichert blockierte Threads
C.LockSupport blockiert und aktiviert Threads
Kernattribute
Zustandszustandswert
Knotenstatus (waitStatus)
-2 Der aktuelle Thread blockiert und gibt gleichzeitig die Sperre frei
-1 weckt den Thread nachfolgender Knoten<br>
AQS-Anwendungsszenarien
Die zugrunde liegende Implementierung von Lock Lock
Faire Sperre und unfaire Sperre
Der Standardwert ist unfaire Sperre
Zeit der Konfliktsperre
Faire Sperre: Wenn die Sperre beim Wettbewerb um eine Sperre bereits von einem anderen Thread gehalten wird, wird sie direkt am Ende der doppelt verknüpften Liste gespeichert.
Unfaire Sperre: Wenn beim Wettbewerb um eine Sperre die Sperre bereits von einem anderen Thread gehalten wird, wird CAS trotzdem erneut versucht.
Grundlegende Designprinzipien
lockmethod()
Verwenden Sie CAS, um den Statuswert in der AQS-Klasse von 0 auf 1 zu ändern
Wenn die Änderung erfolgreich ist (die Sperre wurde erfolgreich erworben)
Wenn die Änderung fehlschlägt (die Sperre konnte nicht erhalten werden)
In der doppelt verknüpften AQS-Liste gespeichert
unlockmethod()
Verwenden Sie CAS, um den Status in der AQS-Klasse von 0 auf 1 zu ändern
Wenn CAS erfolgreich ist
Der vom nächsten Knotenknoten des Hauptknotens in der doppelt verknüpften AQS-Liste zwischengespeicherte Thread muss aktiviert werden
Frage: Warum gibt Unlock die Sperre frei und aktiviert nur einen Thread statt mehrerer Threads?
Die unterste Ebene verwendet eine bidirektionale verknüpfte Liste zum Speichern blockierter Threads. Die Kosten für das Aufwecken aller Threads sind sehr hoch.
Im Schloss gibt es keinen Sperraktualisierungsprozess, und Entwickler müssen es selbst erweitern.
ConcurrentHashMap1.7-Quellcode, der Lock zugrunde liegt
Zustand
Hinweis: Bedingung und Sperre verwenden nicht dieselbe doppelt verknüpfte Liste
Pool sperren und Pool warten
Sperrpool: Bezieht sich auf die Threads in der Sperre, die nicht um die Sperre konkurrieren konnten, und werden in der doppelt verknüpften AQS-Liste gespeichert.
Wartepool: Bezieht sich auf den aktuellen Thread, der die Wartemethode aufruft, die Sperre aktiv aufhebt (aqs-Statuswert = 0) und sie in der doppelt verknüpften Liste des Wartepools speichert
Wie wecke ich den Thread im Wartepool auf?
Durch Aufrufen dieses Signals () werden nur die Knotenknoten (Threads) im Wartepool an den AQS-Sperrpool für doppelt verknüpfte Listen übertragen, um erneut um die Sperrressourcen zu konkurrieren.
Nach dem Aufruf dieses Signals () und dem Aufruf der Entsperrmethode beginnen die Threads im Wecksperrenpool, um Sperrressourcen zu konkurrieren.
CountDownLatch(Zähler)
Durch den Konstruktor new CountDownLatch(1)
Die zugrunde liegende Implementierung basierend auf AQS setzt den Statuswert in der AQS-Klasse auf 1
Warten Sie auf die Methode
Speichern Sie den aktuellen Thread-Block in der doppelt verknüpften AQS-Liste
Countdown
Betreiben Sie den Statuswert -1 in der AQS-Klasse. Wenn der AQS-Status auf 0 geändert wird, aktivieren Sie den Thread, der in der doppelt verknüpften Liste in der AQS-Klasse gespeichert ist.
Semaphor(Semaphor)
Durch den Konstruktor new Semaphore(3)
Die zugrunde liegende Implementierung auf Basis von AQS setzt den Statuswert in der AQS-Klasse auf 3
Die zugrunde liegende Operation des Erwerbs besteht darin, den Statuswert -1 in der AQS-Klasse zu ändern. Wenn der Statuswert in der AQS-Klasse auf 0 geändert wird, muss der aktuelle Thread blockiert und in der doppelt verknüpften Liste in der AQS-Klasse gespeichert werden.
Die unterste Freigabeschicht arbeitet mit dem Status 1 in der AQS-Klasse<br>
Blockierte Threads in der AQS-Klasse gleichzeitig aufwecken (nur einer wird aufgeweckt)
CyclicBarrier (Synchronisationsbarriere)
Durch den Konstruktor new CyclicBarrier(2)<br>
Die unterste Ebene weist dem CyclicBarrier-Zählerattribut einen Wert = 2 zu
Anruf wartet auf unterste Ebene
Operation auf CyclicBarrier count-1
Anzahl=0
Setzen Sie die Ausführung fort und aktivieren Sie alle Threads im Wartepool
zählen!=0
Im Wartebecken gelagert
Gleichzeitige atomare Operationen
Atomklasse
CAS-Prinzip (Optimistic Locking).
Ausführliche Erklärung der Klasse „Unsichere Magie“.
Blocking QueueBlockingQueue-Prinzip
Klassifizierung der blockierenden Warteschlange
ArrayBlockingQueue Array-begrenzte Warteschlange
ConcurrentLinkedQueue verknüpfte Liste mit begrenzter Warteschlange
PriorityBlockingQueue Prioritätssortierung, unbegrenzte Warteschlange
DelayQueue verzögert unbegrenzte Warteschlange
Rahmenanwendung
Handgeschriebener Thread-Pool basierend auf BlockingQueue
Handschriftliche Nachrichten-Middleware basierend auf BlockingQueue
Handgeschriebenes Protokoll-Framework basierend auf BlockingQueue
Detaillierte Erklärung des Executor-Thread-Pools und Analyse des Kernquellcodes
Warum Thread-Pool verwenden?
Wiederverwendbarkeit
Einheitliche Verwaltung
Reaktion verbessern
Vier Möglichkeiten zum Erstellen eines Thread-Pools
newCachedThreadPool(); Cachebarer Thread-Pool
newFixedThreadPool(); kann in der Länge festgelegt werden und die maximale Anzahl von Threads begrenzen
newScheduledThreadPool(); kann geplant werden
newSingleThreadExecutor(); Singleton
Die eigentliche unterste Ebene basiert auf dem Konstruktor-Kapselungs-Thread-Pool ThreadPoolExecutor
Analyse der Kernprinzipien des Thread-Pools
LinkedBlockingQueue
Produzenten- und Konsumentenmodell
Warum Alibaba die Verwendung von Executors nicht empfiehlt
Die zugrunde liegende Verwendung der unbegrenzten Warteschlange LinkedBlockingQueue ist anfällig für einen Speicherüberlauf
Was tun, wenn die Thread-Pool-Warteschlange voll ist?
Richtlinie verweigern
AbortPolicy verwirft Aufgaben und löst Laufzeitausnahmen aus
CallerRunsPolicy-Ausführungsaufgabe
DiscardPolicy Ignorieren, es passiert nichts
DiscardOldestPolicy verlässt die Warteschlange und tritt zuerst in die Warteschlange ein.
Implementieren Sie die RejectedExecutionHandler-Schnittstelle und passen Sie den Prozessor an
So konfigurieren Sie Thread-Pool-Parameter richtig
CPU-intensiv
Optimale Anzahl Threads = Anzahl CPU-Kerne oder Anzahl CPU-Kerne ±1
Intensiv
Optimale Anzahl von Threads = ((Thread-Wartezeit Thread-CPU-Zeit)/Thread-CPU-Zeit) * Anzahl der CPUs
So passen Sie den Thread-Pool basierend auf ThreadPoolExecutor an
Interpretation des FutureTask-Quellcodes
Implementierung von FutureTask basierend auf LockSupport
Implementierung von FutureTask basierend auf Wait/Notify
Interpretation des ForkJoin-Quellcodes
Gleichzeitige Programmierentwicklung
Arbeitsdiebstahlmechanismus
Fork-Join-Prinzip
Interpretation des Threadlocal-Quellcodes
Was ist Threadlocal?
Threadlocal-Anwendungsszenarien
1.Spring-Transaktionsvorlagenklasse
2. Holen Sie sich httprequest
3.Aop-Aufrufkette übergibt Parameter
Der Unterschied zwischen Threadlocal und Synchronized
So verhindern Sie Threadlocal-Speicherlecks
1. Rufen Sie die Remove-Methode auf
2. Bei Verwendung der Set-Methode wird gelöscht, dass der vorherige Schlüssel null war.
Interpretation des Quellcodes des Microservice-Frameworks
Interpretation des SpringBoot-Quellcodes
So funktioniert die automatische SpringBoot-Konfiguration
Interpretation des Quellcodes des SpringBoot-Kernmoduls
Interpretation des Quellcodes der SpringBoot-Kernanmerkung
Interpretation des Quellcodes des eingebetteten SpringBoot-Servlet-Containers
Bereitstellung von SpringBoot-Paketen sowie Betriebs- und Wartungsmanagement
Wie Servlet-Container Webflux überwinden
Interpretation des Quellcodes der Kernkomponente von SpringCloudNetfilix (erste Generation).
Registrierung des Eureka-Dienstes und Interpretation des Discovery-Quellcodes
Erneuerung des Eureka-Dienstes (Heartbeat)
Eliminierung des serverseitigen Eureka-Dienstes
Selbstschutzmechanismus des Eureka-Dienstes
Was passiert, wenn der Dienst ausfällt?
Lokale Dienste verwenden einen Wiederholungsmechanismus
Der lokale Dienst implementiert Adress-Failover
Offline-Benachrichtigung des Eureka-Dienstes
Eureka-Cluster-Datensynchronisierung
Interpretation des deklarativen Serviceaufruf-Quellcodes von Fegin
Hystrix implementiert die Begrenzung des Betriebsstroms, die Herabstufung und die Interpretation des Leistungsschalter-Quellcodes
Ausführliche Erläuterung des einheitlichen Zuul-Gateways, des Service-Routings und der Interpretation des Filterquellcodes
Interpretation des Quellcodes des verteilten Konfigurationscenters konfigurieren
Interpretation des verteilten Link-Tracking-Quellcodes von Sleuth
Detaillierte Erläuterung des Ribbon-Client-Lastausgleichs und Quellcode-Analyse
Interpretation des Quellcodes von SpringCloudAlibaba (zweite Generation).
Interpretation des Quellcodes des verteilten Registrierungszentrums von Nacos
Dienstregistrierung und -erkennung
Registrierung des Nacos-Dienstes und Interpretation des Quellcodes der Entdeckung
Prinzip der Dienstregistrierung
eurekaClient
Verwenden Sie JerseyClient, um eine Registrierungsanfrage zu senden
eurekaServer-Seite
Verwenden Sie ConcurrentHashMap, um Schnittstellenadressen zwischenzuspeichern
Schlüssel ist der Dienstname
Der Wert ist die Cache-Schnittstellenadresse
Naocs-Service-Heartbeat-Erkennung und Interpretation des Erneuerungsquellcodes
Standardmäßig sendet EurekaClient alle 30 Sekunden ein Heartbeat-Erneuerungspaket, um die Zeit zu verlängern und EurekaServer mitzuteilen, dass ich noch am Leben bin.
Standardmäßig sucht EurekaServer alle 60 Sekunden in der Cache-Adresse nach abgelaufenen Adressen, speichert sie in einer neuen Sammlung und löscht sie mithilfe eines Zufallsalgorithmus.
Naocs-Dienst offline und Interpretation des Quellcodes zur Integritätsprüfung
Interpretation des Quellcodes des Nacos-Cluster-Raft-Wahlalgorithmus
Langer Polling-Verarbeitungsmechanismus des Nacos-Servers
Prinzip der Datensynchronisation zwischen Nacos-Clusterknoten
Interpretation des AP-Modus-Quellcodes in Nacos
Interpretation des CP-Modus-Quellcodes in Nacos
Nacos-Cluster-Split-Brain-Lösung
Verteiltes Konfigurationscenter
Implementierungsprinzip des verteilten Nacos-Konfigurationszentrums
So aktualisieren Sie Konfigurationsdateien in Nacos dynamisch
Gateway Interpretation des Microservice-Gateway-Quellcodes der neuen Generation
Warum ist die Gateway-Leistung besser als die Zuul-Leistung?
Analyse des dynamischen Gateway-Routing-Quellcodes
Geben Sie die Route zur Zeitregelübereinstimmung an
Cookie-Matching-Route
Header-Matching-Route
Host-Matching-Route
Anforderungsmethode, die mit der Route übereinstimmt
Fordern Sie eine passende Route für den Pfad an
Analyse des Gateway-Filter-Quellcodes
Benutzerdefinierter GatewayFilter
Gateway integriert Nacos, um einen Lastausgleich zu erreichen
Gateway integriert Sentinel, um eine Gateway-Strombegrenzung zu implementieren
Interpretation des Quellcodes des verteilten Transaktionsframeworks von Seata
Interpretation des Quellcodes der drei Kernkomponenten von Seata zur Lösung verteilter Transaktionen
Seata generiert umgekehrt eine SQL-Anweisung basierend auf der Undo_log-Tabelle und setzt die Interpretation des Quellcodes zurück
Interpretation des Quellcodes des globalen Sperrdesigns der Seata-Zweigtransaktion
Interpretation des GlobalTransactionalInterceptor-Quellcodes
Wie TM eine Remote-Verbindung zu TC herstellt, um die Interpretation des Quellcodes der globalen Transaktions-ID zu erhalten
Ausführliche Quellcode-Interpretation des Quellcodes der Vorder- und Rückspiegel von Seata
Was sind die Unterschiede zwischen Seata und LCN-Rollback?
Interpretation des Quellcodes des Canal Distributed Data Synchronization Framework
Interpretation des Quellcodes der Gesamtarchitektur des Kanals
Architekturanalyse des MySQL-Master-Slave-Replikationsprinzips
Wie Canal vorgibt, BinLog-Dateien von Knoten zu abonnieren
Designprinzipien von EventParser und EventSink
Kanal-inkrementelles Abonnement-/Verbrauchsdesignprinzip
Kanal-Leistungsoptimierung bei gleichzeitiger Datensynchronisierung
So reduzieren Sie die Latenz der Synchronisierung zwischen Daten
So vermeiden Sie die Konsistenz der Nachrichtensequenz bei der Datensynchronisierung
So vermeiden Sie das Problem des Verlusts der Datensynchronisation
Wächter
Dienstisolation
Strombegrenzungsalgorithmus
Token-Bucket
undichter Kübel
Basierend auf Semaphor Semaphor implementiert
Zählfenster korrigiert
Fenster mit Schiebetechnik
Regeln zur Flusskontrolle
Themen
Basierend auf Semaphor Semaphor implementiert
QPS
Token-Bucket
Hystrix
Regeln zur Flusskontrolle
Semaphor-Isolation
Im Sentinel
QPS
Token-Bucket
Thread-Pool-Isolierung
Fehler verbrauchen CPU-Ressourcen
Strombegrenzungsmethode
Google Guava(RateLimiter)
Alibaba Sentinel
Nginx
Redis Lua implementiert die Strombegrenzung
Es wird empfohlen, die Strombegrenzung auf Nginx oder Gateway vorzunehmen
Interpretation des Quellcodes des Sammlungsframeworks
Hash (Hash-Funktion) Interpretation des Quellcodes des Kartensammlungs-Frameworks
Grundwissen
Der Unterschied zwischen == und equal und die zugrunde liegende Implementierung
Warum Gleiches umschreiben und auch Hashcode umschreiben?
Binär- und Dezimalkonvertierung/^ (exklusive ODER-Verknüpfung)/>>> (vorzeichenlose Rechtsverschiebung)/ & (UND-Verknüpfung)
Low-Level-Implementierung
JDK1.7
Array-verknüpfte Liste
Kopfeinfügungsmethode (Problem mit gleichzeitiger Erweiterung und Endlosschleife)
Das Schreiben von Code ist einfach
JDK1.8
Array-verknüpfte Liste rot-schwarzer Baum
Methode zum Einführen des Schwanzes
High-End-Code-Schreiben
Rot-Schwarz-Baumumwandlung
(Array-Kapazität >= 64 und Länge der verknüpften Liste größer als 8)
Anzahl der rot-schwarzen Baumknoten <6, konvertierte verknüpfte Liste
Berechnung der Hash-Funktion
(h = key.hashCode()) ^ (h >>> 16)
i = (n - 1) & Hash
Zeitkomplexität
Der Schlüssel steht nicht in Konflikt
Die Zeitkomplexität beträgt O(1)
Schlüsselkonflikt
Der Speicher für verknüpfte Listen ist O(N)
Der Rot-Schwarz-Baumspeicher ist O(LogN)
Hashcode-Kollisionsproblem
Die Hashcode-Werte sind gleich, aber die Inhaltswerte sind unterschiedlich.
Merkmale:
Der Schlüssel ist null, um die 0-Position des Arrays zu speichern.
Implementiert mithilfe einer einseitig verknüpften Liste
Ungeordneter Hash-Speicher
Leistungsoptimierung
So vermeiden Sie Speicherverlustprobleme mit HashMap
Wie HashMap die Wahrscheinlichkeit von Hash-Konflikten reduziert
So geben Sie die Anfangswertgröße der Sammlung in HashMap sinnvoll an
Häufige Fragen im Vorstellungsgespräch zu HashMap
Warum sollten wir die HashCode-Methode neu schreiben, wenn wir Equals neu schreiben?
Wie HashMap Speicherverlustprobleme vermeidet
Wie wird die unterste Ebene von HashMap1.7 implementiert?
Wo wird der HashMapKey als Null gespeichert?
Wie wird die unterste Ebene von HashMap1.7 implementiert?
Wo wird der HashMapKey als Null gespeichert?
Wie HashMap das Hash-Konfliktproblem löst
Wie HashMap das Array-Erweiterungsproblem implementiert
Verwendet die unterste Ebene von HashMap eine einfach verknüpfte Liste oder eine doppelt verknüpfte Liste?
Zeitliche Komplexität der HashMap-Abfrage basierend auf dem Schlüssel
Was sind die Unterschiede zwischen HashMap1.7 und 1.8?
So vermeiden Sie das Endlosschleifenproblem der Multithread-Erweiterung in HashMap1.8
Warum muss HashMap1.8 rot-schwarze Bäume einführen?
Warum beträgt der Ladefaktor 0,75 statt 1?
Wie verringert die unterste Ebene von HashMap die Wahrscheinlichkeit von Hash-Konflikten?
Wie speichert HashMap 10.000 Schlüssel am effizientesten?
Welche Vorteile bieten die High- und Low-Bits und Modulo-Operationen von HashMap?
Warum nicht einfach den Schlüssel als Hashwert verwenden, sondern eine XOR-Operation mit den hohen 16 Bits durchführen?
Wie wird die Hash-Funktion in HashMap implementiert?
Wird die unterste Ebene von HashMap in der richtigen Reihenfolge gespeichert? <br>
Wie erreichen die zugrunde liegenden Ebenen von LinkedHashMap und TreeMap eine Ordnung?
So verwenden Sie HashMap in Situationen mit hoher Parallelität
Das Prinzip der zugrunde liegenden Implementierung von ConcurrentHashMap
Interpretation des Quellcodes des ConcurrentHashMap-Sammlungsframeworks
Grundwissen
synchronisiert und gesperrt
So verstehen Sie das Konzept der Segmentierungssperre
CAS-Algorithmus und flüchtig
zugrunde liegende Implementierung
JDK1.7
Datenstruktur
Implementierung der HashEntry-verknüpften Liste mit Segmentierungssperre für Array-Segmente
Implementierung sperren
Sperre Sperre CAS Optimistische Sperre UNSAFE-Klasse
Implementierung der Kapazitätserweiterung
Unterstützt die gleichzeitige Erweiterung mehrerer Segmente
Jdk1.8
Datenstruktur
Verwenden Sie das Knotenarray direkt, um Daten zu speichern
Array-verknüpfte Liste rot-schwarzer Baum
Implementierung sperren
Segmentdesign abbrechen
Der Index kollidiert nicht und verwendet die CAS-Sperre
Indexkonflikte verwenden synchronisiert
Implementierung der Kapazitätserweiterung
Unterstützt die gleichzeitige Erweiterung
Merkmale: Unterstützt Multithreading, hohe Effizienz, standardmäßig in 16 Segmente unterteilt
Merkmale:
ConcurrentHashMap unterstützt keinen Nullschlüssel
Analyse des Quellcodes der Listensammlung
Die zugrunde liegende Arraylist-Implementierung
Datenstruktur
Array
Zeitkomplexität
Zeitkomplexität der tiefgestellten Abfrage o(1)
Erweiterung
Die Erweiterung beträgt das 1,5-fache des Originals
Nicht Thread-sicher
Vorteile und Nachteile
Die Effizienz beim Hinzufügen und Löschen ist gering und erfordert eine Erweiterung, die Abfrageeffizienz ist jedoch relativ hoch.
Vektorbasierte Implementierung
Datenstruktur
Array
Zeitkomplexität
Zeitkomplexität der tiefgestellten Abfrage o(1)
Erweiterung
Die Erweiterung ist doppelt so groß wie das Original
Thread-Sicherheit
Die zugrunde liegende LinkedList-Implementierung
Basierend auf der Datenstruktur der verknüpften Liste, Komplexität der Indexabfragezeit ()
Datenstruktur
verlinkte Liste
Zeitkomplexität
Tiefgestellte Abfragezeitkomplexität log2(n) binäre Suche
Nicht Thread-sicher
Vorteile und Nachteile
Die Effizienz beim Hinzufügen, Löschen und Ändern ist hoch, die Abfrageeffizienz jedoch relativ gering.
Verteilte Architekturlösungen
Design und Praxis der idempotenten Architektur von Internet-Microservices
Was ist idempotentes Design? Idempotenter Produktionshintergrund
Zeitüberschreitung der Clientantwort
Wenn die Geschäftsausführungszeit sehr lang ist, wird empfohlen, stattdessen mq asynchronous zu verwenden.
Wiederholungsrichtlinie
Lösen Sie die Hauptgründe für das idempotente Problem von Serviceschnittstellen
Datenbankebene
Analysieren Sie die Gründe für Idempotenz auf architektonischer Ebene
Gateway-Schicht
Schnittstellenschicht
Fragen Sie vorab ab, ob die Geschäftslogik anhand der globalen ID ausgeführt wurde
DB-Schicht
Eindeutige Anmerkungseinschränkung für den Typ einfügen
Update-Typ optimistischer Sperrmechanismus
Garantiert die globale ID wirklich Schnittstellen-Idempotenz?
Nicht unbedingt, Sie müssen die Datenbankebene berücksichtigen
So stellen Sie die Idempotenz von RPC-Schnittstellen sicher
globale ID
Verriegelungsmechanismus (wegen geringer Effizienz nicht empfohlen)
Implementieren Sie idempotentes Design basierend auf realen Geschäftsszenarien
Design und Praxis der verteilten Sperrarchitektur im Internet
In welchen Szenarien werden verteilte Sperren verwendet?
Das Problem der Sicherstellung der Idempotenz der geplanten Aufgabenplanung
Garantierte Flash-Sales, um Überverkaufsprobleme zu vermeiden
Das wesentliche Implementierungsprinzip verteilter Sperren
Wiederholungsstrategie
Geeignet für eine sehr schnelle Geschäftsabwicklung
Timeout-Kontrolle
Design zur Verlängerung der Lebensdauer
So vermeiden Sie Stillstandsprobleme beim Weiterleben
Leistungsoptimierung
Bedenken Sie den Herdeneffekt
Hohe Verfügbarkeit
Blockierungs-Timeout festlegen
Sperrgranularität reduziert
Gerechtigkeit
Kompatibilitätstests und Wiederherstellungsdesign für verteilte Sperren
Lösung zur verteilten Sperrenimplementierung
Zookeeper implementiert verteilte Sperren (CP-Modus)
Hauptidee
Temporärer Knoten
Einzigartigkeit des Weges
Beobachterereignis
Merkmale
Verwenden Sie den CP-Modus
Vorteil
Angeborene Lösung des Split-Brain-Problems (mehr als die Hälfte des Mechanismus)
Zuverlässiger und stabiler
Mangel
Die Effizienz der Clustersynchronisierungsdaten ist gering
Schlechte Leistung
Zwei Implementierungsmethoden
Basierend auf demselben temporären Knoten implementiert
Es kann zu einem Herdeneffekt kommen
Basierend auf temporären sequentiellen Knoten implementiert
Vermeiden Sie Probleme beim Hüten
Temporärer fortlaufender Nummernknoten
Wenn der aktuelle Knoten der kleinste Knoten ist, bedeutet dies, dass die Sperre erfolgreich erworben wurde.
Wenn der aktuelle Knoten nicht der kleinste Knoten ist, abonnieren Sie den vorherigen Knoten
Kurator-Framework verteilte Sperre
Holen Sie sich die Sperre
Implementierung basierend auf temporären sequentiellen Nummerierungsknoten
Erstellen Sie einen temporären Sequenzknoten, und der kleinste erhält die Sperre.
Block
Der von Ihnen erstellte aktuelle temporäre Sequenzknoten ist nicht der kleinste. Abonnieren Sie den vorherigen Knoten
Sperre lösen
Löschen Sie den temporären fortlaufenden Nummernknoten
Schwierigkeiten bei Vorstellungsgesprächen
Wie kommt es zum Ausfall des ZK-Masterknotens und welche Auswirkungen hat das?
Die ZK-Wiederwahl findet statt und die gesamte ZK-Umgebung ist vorübergehend nicht verfügbar.
Zab-Protokoll muss berücksichtigt werden
Vergleichen Sie zuerst zxid und dann myid
So vermeiden Sie das Deadlock-Problem des ZK-Clients
zkserver ist ausgefallen
Der ZK-Client legt das Blockierungs-Timeout fest
Nach der Überwachung der Ausfallzeit von zk wird es aktiv aktiviert.
Der ZK-Client ist ausgefallen
Die angeborenen Eigenschaften von zk vermeiden Deadlock-Probleme und geben Sperren proaktiv frei
Andere zk-Clients legen ein Blockierungs-Timeout fest
Die JVM, die die Sperre erworben hat, gibt die Sperre niemals frei.
Kontrollieren Sie die Anzahl der Lebensverlängerungen, geben Sie die Sperre nach mehreren Lebensverlängerungen aktiv frei und die Transaktion wird zurückgesetzt
Redis implementiert verteilte Sperren (AP-Modus)
Hauptidee
Setnx implementiert eine verteilte Sperre
Holen Sie sich die Sperre
Mehrere JVMs gleichzeitig gesetzt. Am Ende ist nur ein JVM erfolgreich
Sperre lösen
Löschen Sie den Schlüssel
Merkmale
Verwenden Sie den AP-Modus
Vorteil
Unterstützt hohe Parallelität
Effizienz ist in Ordnung
Verwendung der asynchronen Synchronisationsdatenmethode
Mangel
Angeborenes Split-Brain-Problem (Redis-Cluster verfügt nicht über einen Mehrheitsmechanismus)
Nicht sehr stabil
Der angeborene Einzelthread von Redis kann die Sicherheit von Setnx-Threads gewährleisten
Redisson-Framework
Holen Sie sich die Sperre
Erstellen Sie einen Hash-Schlüssel mit einem Lua-Skript
Sperre lösen
Löschen Sie den Schlüssel
Design zur Verlängerung der Lebensdauer
Standardmäßig wird der Watchdog-Thread alle 10 Sekunden aktiviert, um ein Ablaufen des Schlüssels zu verhindern.
Schwierigkeiten bei Vorstellungsgesprächen
So vermeiden Sie Client-Deadlock-Probleme
Abgelaufenen Schlüssel festlegen
Begrenzen Sie die Anzahl der Lebensverlängerungen
Rollback-Transaktion
Der Schlüssel ist abgelaufen, aber das Geschäft wurde noch nicht ausgeführt. Was soll ich tun?
Design zur Verlängerung der Lebensdauer
Globale Lebensverlängerung (nicht empfohlen)
Inkrementelle Lebensdauerverlängerung (empfohlen)
Standardmäßig wird die Lebensdauer alle 10 Sekunden im Voraus erneuert, um ein Ablaufen des Schlüssels zu verhindern.
Erneuern Sie das Leben mehrmals, um die Anzahl der Lebenserneuerungen aufgrund von Deadlock-Problemen zu begrenzen
Rollback-Transaktion
Sperre aktiv lösen
Was soll ich im Redis-Cluster tun, wenn der Masterknoten ausgefallen ist? <br>
Verwenden Sie den RedLock-Red-Lock-Algorithmus
Im Redis-Cluster gibt es keinen Unterschied zwischen Master und Slave
Der Client erfüllt mehr als die Hälfte der Setnx-Anforderungen für mehrere Redis-Server und erhält die Sperre erfolgreich.
Wenn der Client festlegt, dass die Gesamtzeit, die zum Erhalten der Sperre benötigt wird, > die Ablaufzeit des Schlüssels ist, wird die Sperre automatisch freigegeben.
Dieser Algorithmus verwendet tatsächlich ZK, um verteilte Sperren zu implementieren.
Design und Praxis der Internet-Architektur für verteilte Transaktionen
Der Hintergrund verteilter Transaktionen
Einzelnes Projekt, mehrere Datenquellen
jta Atomikos löst verteilte Transaktionen
RPC-Remote-Aufrufschnittstelle
Distributed Transaction Consistency Protocol
Starkes Konsistenzprotokoll
Im Cluster müssen die Kopierdaten jedes Knotens konsistent sein
Schwaches Konsistenzprotokoll
Im Cluster dürfen einige Knotenreplikate inkonsistente Daten aufweisen
Eventualkonsistenzprotokoll
Kurze Datenverzögerungen sind zulässig, letztendlich ist jedoch Datenkonsistenz erforderlich
Designideen für verteilte Transaktionen
Basis- und CAP-Theorie
Basistheorie
Grundsätzlich verfügbar<br>
weicher Zustand
letztendliche Konsistenz
DECKEL
Grundlegende Theorie
Konsistenz(C)
Im Cluster müssen die Kopierdaten jedes Knotens konsistent sein
Verfügbarkeit(A)
Kann der gesamte Cluster nach dem Ausfall einiger Knoten im Cluster noch auf die Lese- und Schreibanforderungen des Clients reagieren?
Partitionstoleranz (P)
Die Partitionsfehlertoleranz (P) stellt hauptsächlich Fehler dar, die durch unvermeidliche Netzwerkschwankungen verursacht werden. Diese drei Modi können nicht gleichzeitig erreicht werden. Daher gibt es derzeit nur zwei Modi: CP- und AP-Modi
Modusauswahl
CP (garantierte Datenkonsistenz)
Verfügbarkeit nicht garantiert
Ap (garantierte Verfügbarkeit)
Die Datenkonsistenz jeder Kopie kann jedoch nicht garantiert werden<br>
Vergleichende Analyse
Nacos
Nacos unterstützt CP/AP-Cluster im gemischten Modus ab Version 1.0. Standardmäßig ist der Ap-Modus
Heureka
Ap-Modus
Tierpfleger
CP-Modus
Das Registrierungszentrum empfiehlt den Ap-Modus
Flexible und starre Angelegenheiten
Starre Transaktionen erfüllen die ACID-Theorie
Flexible Transaktionen erfüllen die BASE-Theorie (grundsätzlich verfügbar, letztendlich konsistent)
2PC/3PC/TCC<br>
Framework zur verteilten Transaktionsauflösung
LCN löst verteilte Transaktionsprobleme
Seata löst verteilte Transaktionsprobleme
MQ löst verteilte Transaktionsprobleme
TCC löst verteilte Transaktionsprobleme
Wiederholen Sie die Rückrufmethode, um verteilte Transaktionsprobleme zu lösen<br>
Design und Praxis der Internet-Distributed-Task-Scheduling-Architektur
Nachteile herkömmlicher geplanter Aufgaben
Verbrauchen Sie CPU-Ressourcen
Die Nichtentkopplung wirkt sich auf die Geschäftslogik aus
Kernentwurfsideen der verteilten Aufgabenplanung
Protokollrückverfolgbarkeit
Flexible Erweiterung und Kontraktion
Unterstützt parallele Planung
Hochverfügbarkeitsstrategie
Strategie zur Fehlerbehandlung
Dynamische Sharding-Strategie
Framework zur verteilten Aufgabenplanung
Interpretation des XXLJob-Quellcodes
Interpretation des ElasticJob-Quellcodes
MySQL- und Redis-Datenkonsistenzprotokoll
Lösung
1. Aktualisieren Sie die MySQL-Daten und leeren Sie den Redis-Cache manuell
Vorteile: geringe Latenz
Nachteile: Nicht entkoppelt
2. Aktualisieren Sie MySQL-Daten und synchronisieren Sie Daten in Form von MQ asynchron mit Redis
Vorteile: Entkopplung implementieren, Kompensationsstrategie wiederholen, Schnittstellenreaktion verbessern
Nachteile: hohe Latenz
3. Synchronisieren Sie Daten mit Redis basierend auf dem Abonnieren von MySQLBinLog in Kombination mit der asynchronen MQ-Form (Kanal-Framework-Implementierung).
Vorteile: Mehr Entkopplung, Wiederholungskompensationsstrategie, verbesserte Schnittstellenreaktion
Nachteile: Die Latenz wird immer höher
Kernideen für das Design
Die Idee der letztendlichen Konsistenz besteht darin, dass vorübergehende Dateninkonsistenzen zulässig sind, die endgültigen Daten jedoch konsistent sein müssen.
Prinzip des Double-Write-Konsistenzprotokolls
Zuerst den Cache löschen und dann die Datenbank aktualisieren (nicht empfohlen)
Doppeltes Löschen muss verzögert und zweimal gelöscht werden
Löschen Sie den Cache zum ersten Mal
Um die Parallelität anderer Threads zu vermeiden, synchronisieren Sie beim zweiten Mal die fehlerhaften Lesedaten mit Redis. Warten Sie also einige Sekunden (die Zeit, in der das zweite Thread-Geschäft die alten Daten auf Redis aktualisiert), um den Cache zu löschen
Aktualisieren Sie zuerst die Datenbank und löschen Sie dann den Cache
Es muss mit mq kombiniert werden und die Konsistenz der Nachrichtensequenz sicherstellen. Das Löschen des Caches muss erfolgreich sein.
DoubleWrite-Konsistenzprotokoll
Was ist doppeltes Schreiben?
Aktualisieren Sie zuerst die Datenbank und dann den Cache
Welche Probleme werden auftreten
In einer gleichzeitigen Situation schreiben mehrere Threads gleichzeitig. Ein anderer Thread schreibt möglicherweise fehlerhafte Lesedaten in den Cache.
So lösen Sie Dirty Reads
Mit dem MySQL-Transaktions-Zeilensperrmechanismus können mehrere Threads gleichzeitig die Zeilensperre erwerben. Nach dem Erwerb der Zeilensperre muss Redis erfolgreich synchronisiert werden Threads können schreiben
Mit verteilten Sperren implementiert (nicht empfohlen, kann direkt basierend auf MySQL-Zeilensperren implementiert werden)
Konstruktionsprinzip des Kanalrahmens
Canal löst das Prinzip der Datensynchronisation zwischen MySQL und Redis
1.canal verkleidet sich als MySQL-Slave-Knoten und abonniert die Binlog-Datei des MySQL-Masterknotens;
2. Wenn sich die Binlog-Datei unseres MySQL-Masterknotens ändert, wird die Binlog-Datei<br> an den Kanalserver gesendet.
3. Der Kanalserver konvertiert die Binlog-Datei in das JSON-Format und sendet sie an den Kanal-Client.
4. Der Kanal-Client synchronisiert die Daten mit Redis/ES;
Synchronisationsmodus des Kanals
TCP (geringe Effizienz)
Kafka (empfohlen)
So verbessern Sie die Effizienz der Kanalintegration der Kafka-Datensynchronisierung
Integrieren Sie den MQ-Themenmodus
Einzelnes Thema und einzelne Partition (globale Binlog-strikte Reihenfolge)
Eine einzelne Partition mit mehreren Themen kann die Reihenfolge auf Tabellenebene sicherstellen.
Derselbe Tabellenname wird in derselben Partition abgelegt und schließlich vom selben Verbraucher verwendet.
Einzelnes Thema, mehrere Themen, mehrere Partitionen kombiniert mit Hash-Modus
So lösen Sie das Problem der Nachrichtensequenzkonsistenz
Richten Sie mehrere Partitionen ein und berechnen Sie den Hash basierend auf den Feldern in der Tabelle, z. B. der Primärschlüssel-ID. Dieselbe ID wird in derselben Partition abgelegt und vom selben Verbraucher verwendet.
Gibt es Verzögerungen bei der Datensynchronisierung zwischen MySQL und Redis?
Während des Datensynchronisierungsprozesses kommt es zu einer kurzen Verzögerung, was normal ist. Es ist schwierig, eine starke Konsistenz zu erreichen und der Idee einer letztendlichen Konsistenz zu folgen.
Prinzip der verteilten Nachrichten-Middleware
Grundlegendes konzeptionelles MQ-Modell
Synchron und asynchron
Beschneidung von Verkehrsspitzen
Skalierbarkeit/Entkopplung
Pufferung/Wiederherstellbarkeit
Produzenten und Konsumenten
Gemeinsame MQ-Lösungen
Wie MQ die Anhäufung von Nachrichten vermeidet
Verbraucherquote erhöhen (Cluster)
Verbraucher erhalten Nachrichten in Stapeln
Wie vermeidet MQ den wiederholten Konsum durch Verbraucher (idempotentes Problem)
Das Geschäftsszenario „Global ID“ sorgt für Einzigartigkeit
Wie stellt MQ sicher, dass Nachrichten nicht verloren gehen?
Mechanismus zur Nachrichtenbestätigung
Beharrlichkeit
Nachricht bestätigen
Wie MQ die Konsistenz der Nachrichtensequenz gewährleistet
Binden Sie denselben Verbraucher und dieselbe Warteschlange
MQ-Push- und Pull-Architekturmodell
Wie Produzenten Konsumergebnisse erzielen
Gibt asynchron eine globale ID zurück und das Front-End verwendet Ajax, um regelmäßig aktiv Abfragen durchzuführen.
Mainstream-MQ-Framework
Rabbitmq
Architektonische Gedanken
Rabbitmq-Verwaltungsplattformzentrum
Virtuelle Hosts
Speichern Sie Nachrichtenwarteschlangen in separaten Teamentwicklungspfaden
Austausch
Routenverteilungsnachricht
Routing-Schlüssel
RabitMQ-Warteschlangenmodell
einfacher Modus<br>
Arbeitsmodus
Broadcast-Modus --- Fanout
Routing-Modus --direct
Themenmodus --topic
RabitMQ vier Schaltertypen
Direkter Austausch (Direktschalter)
Fanout-Austausch
Themenaustausch
Header-Austausch
Häufige Fragen im Vorstellungsgespräch zu RabbitMQ
So stellt RabbitMQ sicher, dass Nachrichten nicht verloren gehen
Hersteller
Stellen Sie sicher, dass der Produzent die Nachricht erfolgreich an den MQ-Server übermittelt
Bestätigungsmechanismus für Bestätigungsnachrichten (Bestätigt)
Synchrone oder asynchrone Form
Transaktionsnachrichten
Verbraucher
Manueller Verbrauchsempfangsmodus
Automatische Signatur (nicht empfohlen)
Manuelle Signatur (empfohlen)
MQ-serverseitige Nachrichtenpersistenz
RabbitMQ-Warteschlange für unzustellbare Nachrichten
Die Nachricht wird an MQ übermittelt und gespeichert. Die Nachricht ist abgelaufen.
Der Warteschlangencontainer ist voll
Wenn es dem Verbraucher nicht gelingt, mehrere Nachrichten zu konsumieren, werden sie in die Warteschlange für unzustellbare Nachrichten übertragen.
Automatischer Wiederholungsmechanismus für RabbitMQ-Nachrichten
Was soll ich tun, wenn ich nach mehrmaligem Versuch immer noch scheitere?
Zur Warteschlange für unzustellbare Nachrichten wechseln
Tragen Sie in der Protokolltabelle die geplante oder manuelle Kompensation ein
Wie vermeidet man Verbraucher-Idempotenzprobleme?
Das Geschäftsszenario „Global ID“ sorgt für Einzigartigkeit
Kafka
Kafka-Kernarchitektur-Designmodell
Broker (MQ-Serverseite)
Thema (Themen sind nach Branchen geordnet)
Partition (Partitionsspeichernachricht)
Hersteller
Verbraucher
Verbrauchergruppe
Replik (Replika-Mechanismus)
Offset (Verbrauchserfassung)
Warum Kafka hohe Parallelität unterstützen kann
Lagerstrukturebene
Nachrichten werden komprimiert, um die Übertragungsbandbreite zu reduzieren
Kafka-Partitions-Partitionsspeicherstrukturmodell
.log-Speichernachrichtendatei
.index speichert den Index der Nachricht
.timeIndex, Zeitindexdatei
Segmentiertes Speicherprotokoll (Segmentdatei)
Verwenden Sie einen Sparse-Index, um den physischen Speicherort der Nachricht zu ermitteln (es wird kein Index für jede Nachricht erstellt).
Vorteile: Platz sparen
Nachdem die Nachricht gespeichert wurde, wird sie nach erfolgreichem Verbrauch nicht sofort gelöscht. Die Nachricht wird basierend auf dem Offset abgerufen (Sie müssen die Konfiguration der Protokollbereinigungsstrategie in Betracht ziehen).
Java-Anwendungsebene
Hersteller
Produzenten übermitteln Nachrichten in Stapeln (Pufferpool-Design)
Verbraucher
Verbraucher erhalten Nachrichten in Stapeln (mehrere Offsets)
Ein Verbraucher pro Partition (Skalierbarkeit)
Linux-Kernel-Ebene
Verwenden Sie sequentielles Lesen und Schreiben
Verwenden Sie den Zero-Copy-Mechanismus
sendfile mmap Benutzermodus- und Kernelmoduszuordnung
Es ist keine CPU erforderlich, Daten zu kopieren
Reduzieren Sie die Anzahl der Wechsel zwischen Benutzermodus und Kernelmodus
Verwenden Sie den Seitencache, um das Lesen und Schreiben zu verbessern
Das Problem des Scheibenbürstens muss berücksichtigt werden
Wie Kafka für zuverlässige Nachrichten sorgt
Reproduzieren
Zuverlässiger Mechanismus der ISR-Replik
Replikatwahl in Partition
HW-Hochwassermarke: der maximale Offset, den Verbraucher verbrauchen können
Der größte Offsetwert in der LEO-Warteschlange
Der Produzent übermittelt die Nachrichtenbestätigung
0 bedeutet, dass der Produzent nicht wartet (Nachrichten können verloren gehen)
1 bedeutet, dass der Produzent wartet und der Anführer die Festplatte leert (Standardkonfiguration empfohlen)
-1 bedeutet, dass der Produzent warten muss, bis alle Knoten synchronisiert sind.
Kafka-Wahlprinzip-Controller-Prinzip
Verlassen Sie sich bei der Durchführung von Wahlen auf temporäre Zookeeper-Knoten
Der Verbraucher übermittelt den Ausgleich manuell
Wie findet Kafka die Nachricht mit einem bestimmten Offset?
1. Segmentdateien basierend auf dem Offset durchsuchen (binäre Suche)
2. Greifen Sie auf die Indexdatei (Sparse-Index) zu und suchen Sie den entsprechenden physischen Speicherort
3. Greifen Sie je nach Standort des physischen Zugriffs auf das Protokoll zu, um die entsprechende physische Nachricht zu finden.
Suchen Sie den Nachrichtenindexwert
Physische Nachrichten direkt zurückgeben (Zeitkomplexität o(1))
Der Nachrichtenindexwert wurde nicht gefunden
Suche nacheinander (Zeitkomplexität o(N))
Kafka-Leistungsoptimierung
Hersteller
Puffergröße des Producer-Speichers
Wiederholungsrichtlinien „retries“ und „retries.backoff.ms“
Dieser Parameter legt die Anzahl der Wiederholungsversuche und das Intervall fest.
Bestätigungsmechanismus: acks Es wird empfohlen, ihn aus Gründen des Gleichgewichts auf 1 zu setzen
Verbraucher
Die Anzahl der Verbraucherpartitionen
Verbraucher erhalten Nachrichten stapelweise basierend auf mehreren Offsets
Der Verbraucher ermöglicht die manuelle Offset-Übermittlung
Broker (MQ-Serverseite)
Konfiguration der Protokollaufbewahrungsrichtlinie
Strategie zum Löschen von Protokolldatendateien
Replikat-Replikationskonfiguration
Optimierung der Netzwerk- und IO-Thread-Konfiguration
Praktische MySQL-Leistungsoptimierung
MySQL-Leistungsoptimierung
Prinzipien der MySQL-Architektur und des Ausführungsprozesses
Wie SQL-Anweisungen ausgeführt werden
Integrierter Abfrage-Cache
Grammatik und lexikalisches Parsen
semantischer Prozessor
Optimierer/Ausführungsplan
Abfrageausführungs-Engine
InnoDb-Speicherstruktur und Festplattenstruktur
Pufferdesign
Pufferpoolfunktion
Der Speicherpuffer ist voll, was tun?
Wie konfiguriere ich die Größe Ihres Pufferpools?
Probleme mit der MySQL-Latenz und Strategien zum Löschen von Daten
So verstehen Sie die abstrakte Datenseiteneinheit in MySQL
Wie korrespondieren Datenseiten und Cache-Seiten auf der Festplatte miteinander?
Welche Beschreibungsinformationen entsprechen der Cache-Seite?
So richten Sie den Pufferpool basierend auf der Maschinenkonfiguration entsprechend ein
Wie viel Speicher sollte für den Pufferpool in einer Produktionsumgebung festgelegt werden?
Gesamtgröße = 2-mal (Chunk-Größe * Anzahl der Pufferpools)
Das Prinzip des zugrunde liegenden MySQL-Kommunikationsprotokolls
Linux
TCP/IP-Socket
MySQL-Nachricht
Drei-Wege-Handshake-Authentifizierung
Unix-Socket
Fenster
benannte Pfeife
Speicherfreigabe
Aufteilung der zugrunde liegenden MySQL-Module
Initialisierungsmodul
Kern-API
Netzwerkinteraktionsmodul
Modul für Client- und Server-Interaktionsprotokoll
Benutzermodul
Zugangskontrollmodul
Verbindungsmanagement, Verbindungsthreads und Thread-Management
Modul zum Parsen und Weiterleiten von Abfragen
Abfrageoptimierungsmodul
Protokollierungsmodul
Schnittstellenmodul der Speicher-Engine
Das zugrunde liegende Implementierungsprinzip des MySQL-Index
Indexdatenstrukturmodell
Hash-tabelle
binärer Suchbaum
roter schwarzer Baum
Ausgewogener Multi-Fork-Suchbaum
B Bäume
Welche Kategorien gibt es im Index?
Volltextindex
Primärschlüsselindex
kombinierter Index
eindeutiger Index
Der Unterschied zwischen innodb und myisam Der Unterschied im Index<br>
Grundprinzipien für die Einrichtung und Verwendung von MySQL-Indizes
Die zugrunde liegenden Prinzipien von MySQL-Transaktionen
Der Unterschied zwischen Spring-Deklaration und Programmiertransaktion
Welche Probleme treten auf, wenn die Transaktion nur beginnt und kein Commit/Rollback durchgeführt wird?
MySQL-Multiversionssteuerungs-MVCC-Prinzip
Isolationsstufe der MySQL-Transaktion
wiederholbare Lektüre
Commit lesen
Unverbindlich lesen
Serialisierung
MySQL-Prinzipien zum Sperren und Freigeben von Sperren
Zeilensperre, Tabellensperre, Seitensperre
Pessimistische Sperre/optimistische Sperre
Lückensperre
Was ist eine Lückensperre?
Warum ist Gap Lock der Hauptgrund, um Phantom-Lesevorgänge unter der RR-Isolationsstufe zu verhindern?
Primärschlüsselindex/eindeutiger Index Wird dem aktuellen Lesevorgang eine Lückensperre hinzugefügt?
Ob die Lückensperre durch eine Bereichsabfrage hinzugefügt wird
Wird Gap zum aktuellen Lesevorgang hinzugefügt, wenn die Suchbedingungen nicht vorhanden sind?
Prinzip der Deadlock-Analyse
Zweiphasenverriegelung
Warum kommt es zu einem Deadlock?
Das zugrunde liegende Prinzip von MySQLUndo-Protokoll
Der Unterschied zwischen Undo-Log und Redo-Log
UndoLog implementiert das Prinzip der Transaktionsatomizität
RedoLog implementiert das Prinzip der Transaktionspersistenz
Praktische MySQL-Leistungsoptimierung
Analyse und Lösungen langsamer SQL-Abfragen
So aktivieren Sie die langsame MySQL-Abfrage
Interpretation des Prinzips der Ausführungsplan erklären
id: Je größer die Spalte, desto höher die Ausführungspriorität. Wenn die ID gleich ist, wird sie von oben nach unten ausgeführt. Wenn die ID NULL ist, wird sie zuletzt ausgeführt.
select_type: gibt den Typ der Abfrage an
Tabelle: Erklären Sie, auf welche Tabelle eine Zeile zugreift.
Typspalte
System
const
eq_ref
ref
<p class="MsoNormal"><b><span style="font-family: "Times New Roman"; Schriftgröße: 10,5pt;">Bereich </span></b></p>
Index
ALLE
Extra bedeutet zusätzliche Informationen
Prinzipien der SQL- und Indexoptimierung
Befolgen Sie die beste linke Präfixregel, um Indexfehler zu verhindern
Versuchen Sie, abdeckende Indizes zu verwenden, um Tabellenrückfragen zu vermeiden
Die Sortierung erfolgt nach der besten Methode mit dem linken Präfix, um eine Dateisortierung zu vermeiden
Der Mindesttyp erfüllt die Bereichsabfrageebene
Paginierungsoptimierung, bei der die ID-Bedingung OffSet filtert oder eine Unterabfrage die ID-Zuordnung findet
Die Join-Tabellenabfrage optimiert kleine Tabellen, um große Tabellendaten zu steuern. Es ist verboten, Join für mehr als drei Tabellen zu verwenden.
So folgt Fuzzy der Regel des besten linken Präfixes oder verwendet eine zusammengesetzte Index-Fuzzy-Abfrage
Prinzipien der MySQL-Konfigurationsoptimierung
Optimierung der Speicher-Engine und der Tabellenstruktur
Alibaba-Entwicklungshandbuch: Optimierung von MySQL aus der Perspektive
MySQL-Tabelle und Datenbank
Wenn die einzelne Tabelle die maximale Größe erreicht, wird sie in Tabellen und Datenbanken unterteilt.
Der Unterschied zwischen horizontalen und vertikalen Teilungen
Untertabellen- und Unterdatenbankstrategie
Rest/Bereich Modulo
Nach Bereich aufgeteilt
Aufgeteilt nach Datum
Aufgeteilt nach Monat
Shard nach Aufzählungswert
Binäres Modulo-Range-Slicing
Konsistentes Hash-Sharding
Partition wie durch das Zielfeldpräfix angegeben<br>
Segmentieren Sie den Modulo-Bereich entsprechend dem Präfix-ASCII-Code und -Wert
Entwickleranpassung
häufiges Problem
Welche Vor- und Nachteile hat die Abfrage nach der Tabellen- und Datenbankpartitionierung?
So implementieren Sie eine Paging-Abfrage nach der Aufteilung von Tabellen und Datenbanken
So implementieren Sie eine Verknüpfungstabellenabfrage nach der Aufteilung von Tabellen und Datenbanken
Warum MyCat nicht empfohlen wird
Netty, ausführliche Quellcode-Interpretation
Konzeptionelle Grundlage des Netzwerkmodells
Fünfschichtiges TCP/IP-Architekturmodell
Anwendungsschicht
Transportschicht
Netzwerkschicht
Datenübertragungsebene
physikalische Schicht
Socket-Netzwerkprogrammierung
TCP-Protokoll
UDP-Protokoll
So lösen Sie das IP-Adressprinzip durch Eingabe einer URL-Adresse
Die zugrunde liegenden Prinzipien des HTTP-Protokolls
Anforderungs- und Antwortprinzip des HTTPS-Protokolls
HTTPS- und SSL/TLS-Prinzipien
Der Unterschied zwischen http-Protokoll und Socket
IO-Modellprinzip
Blockierendes E/A-Modell
Nicht blockierendes I/O-Modell
Multiplex-I/O-Modell
Signalgesteuertes I/O-Modell
Asynchrones I/O-Modell
Der Unterschied zwischen NIO und BIO
AIO-Grundprinzipien
Die Entwicklung von BIO zu NIO
Streamorientiert und pufferorientiert
Blockierend und nicht blockierend
NIO-Implementierungsprinzip (Betriebssystemkernel)
Kernkonzept
Kernel-Puffer
Prozesspuffer
Linux Kernel
wählen
Die Zeitkomplexität beträgt O(n) und es gibt bestimmte Einschränkungen bei der Überwachung von Dateideskriptoren.
Umfrage
Die zeitliche Komplexität beträgt O(n) und es gibt keine Begrenzung für das Abhören von Dateideskriptoren.
epoll
Die zeitliche Komplexität beträgt O(1) und es gibt keine Begrenzung für das Abhören von Dateideskriptoren.
Interpretation des Netty-Quellcodes
Netty häufige Nutzungsszenarien
RPC-Framework
Tomcat-Server
Online Spiel
NIO-Architekturprinzipien
Puffer
Wähler
Gang
Nettiges Hochleistungsdesign
Asynchrone, nicht blockierende Kommunikation
Nullkopie/Speicherpool
MMAP schreiben
Datei senden
Worüber Sie nachdenken sollten:
So reduzieren Sie die Anzahl der CPU-Kopien
Direktspeicher-DMA-Kopierprinzip
So reduzieren Sie die Anzahl der Kernel-Switches
Effizientes Reactor-Threading-Modell
Einzelreaktor-Einzelthread
Einzelreaktor-Multithreading
Reaktor-Master-Slave-Modell
Schlossfreies serielles Designkonzept
Unterstützung des Serialisierungs-Frameworks
Interpretation des Netty-Quellcodes
Netty-Thread-Modell und Quellcode-Analyse
Leistungsstarke Serialisierungsprotokoll-Protobuf- und Quellcode-Analyse
Phänomen und Lösung des Sticky-Packet-Entpackens, Codec-Quellcode-Analyse
Detaillierte Erläuterung des Direktspeichers und der Netty-Zero-Kopie
Netty-Framework-Praxis
Basierend auf dem handgeschriebenen RPC-Framework von Netty (hohe Nachahmung von Dubbo)
Basierend auf Nettys handschriftlicher Multiplayer-Online-Version des Backgammon-Spiels
Basierend auf dem handgeschriebenen Webserver von Netty (Tomcat mit hoher Nachahmung)
Analyse der Kernelprinzipien des Linux-Systems
Vorbereitungsarbeiten für den Linux-Kernel
Eine kurze Analyse der Linux-Kernel-Architektur
Der Unterschied zwischen Linux-Architektur und Kernel-Struktur
Linux-gesteuerter Plattformmechanismus
Linux-Kernel-Architektur
Interpretation des Quellcodes des Spring System Framework
Interpretation des Spring5-Quellcodes
Interpretation des SpringMVC-Quellcodes
Interpretation des SpringBoot-Quellcodes
Neues E-Commerce-Projekt für den Einzelhandel
Ideen für die Architekturgestaltung
Neues Einzelhandelskonzept<br>
Technischer Architekturplan
SpringBoot
SpringCloudAlibaba
Zwischendesign
Technisches Zentrum
Geschäftszentrum
Organisationszentrum
Cloud Computing
SaaS (Software as a Service)
PaaS (Plattformdienst)
IaaS (Infrastrukturdienste)
Betriebs- und Entwicklungsintegration von Devops und K8S
Apm
Implementieren Sie Service-Tracking
Überwachungsalarm
Trennung von Front- und Back-End
Front-End-----vue ähnelt der Ajax-Technologie und wird von Front-End-Ingenieuren implementiert
Backend ------ Schnittstellenform Backend-Ingenieur implementiert Java
Bauen Sie Infrastrukturdienste auf
Stellen Sie das Nacos-Service-Registrierungscenter/Konfigurationscenter bereit
Erstellen Sie einen privaten Maven-Server auf Unternehmensebene
Implementieren Sie den Aufruf der RPC-Schnittstelle im Microservice-Team
Definieren Sie das API-Schnittstellenspezifikationsprotokoll
Erstellen Sie eine Code-Warehouse-Verwaltungsplattform auf Unternehmensebene
po/do/vo/dto/bo Anwendung auswählen
Der Zweck besteht darin, die Sicherheit der von RPC übermittelten Daten zu gewährleisten
App auswählen
DO (Datenobjekt): Entspricht eins zu eins der Datenbanktabellenstruktur und überträgt Datenquellenobjekte über die DAO-Schicht nach oben.
DTO (Data Transfer Object): Datenübertragungsobjekt, ein Objekt, das von einem Dienst oder Manager extern übertragen wird
BO (Geschäftsobjekt): Geschäftsobjekt. Objekt, das die von der Serviceschicht ausgegebene Geschäftslogik kapselt
AO (Anwendungsobjekt): Anwendungsobjekt. Abstraktes Wiederverwendungsobjektmodell zwischen Web-Layer und Service-Layer
VO (View Object): Anzeigeebenenobjekt, normalerweise ein Objekt, das vom Web an die Ebene der Template-Rendering-Engine übertragen wird
Design des Mitgliederzentrums
Implementierung der Login-Schnittstelle
Warum nicht die Sitzung verwenden?
Wenn die Sitzung auf dem JVM-Server gespeichert wird, muss das Problem der Knotenclustersynchronisierung berücksichtigt werden.
Token-Implementierungsmethode
Umsetzungsprinzip
Generieren Sie nach dem Zufallsprinzip ein Token (UUID) als Schlüsselwert von Redis als Benutzer-ID
Geben Sie das Token an den Client zurück, und der Client ruft die Schnittstelle jedes Mal auf, wenn er das Token übergibt.
Vorteile und Nachteile
Vorteil
Parameterauthentizität ausblenden
Mangel
Die Redis-Abfrage muss durchlaufen werden
JWT-Implementierung
Komponenten
Kopfzeile(Kopfzeile)
Nutzlast(Nutzlast)
Unterschrift
Vorteile und Nachteile
Vorteil
Es ist nicht erforderlich, Benutzerdaten auf dem Server zu speichern, wodurch der serverseitige Druck verringert wird
Der leichte JSON-Stil ist relativ einfach
sprachenübergreifend
Mangel
Der Gültigkeitszeitraum kann nicht aktualisiert werden
Ein JWT kann nicht zerstört werden
So implementieren Sie die Abmeldung in Jwt
Browser-Cookies löschen (der Server existiert jedoch noch)
Es empfiehlt sich, die Zeit etwas kürzer einzustellen
Integrieren Sie Multithreading und Thread-Pooling
Verwenden Sie Multithreading, um nach der Anmeldung gesendete E-Mails, Textnachrichten und Gutscheine zu verarbeiten und so die Effizienz der Schnittstellenantworten zu verbessern.
Große Projekte nutzen die asynchrone und zeitaufwändige MQ-Verarbeitung, um die CPU-Ressourcen des Servers zu reduzieren.
SSO-Single-Sign-On
Web-Formular
Wird auf Basis von Cookies umgesetzt
Trennung von Front- und Back-End
Implementiert basierend auf Token oder JWT
häufiges Problem
So erhalten Sie die IP-Informationen des echten Kunden
Durch Festlegen der echten IP des Benutzers in Nginx
So lösen Sie das domänenübergreifende Problem der Front-End- und Back-End-Trennung
Verwenden Sie JSONP, unterstützen Sie jedoch keine Post-Anfragen (nicht empfohlen).
Verwenden Sie die SpringMVC @CrossOrigin-Annotation (empfohlen)
Lösen Sie domänenübergreifende Probleme basierend auf dem Gateway (empfohlen)
Zugriff basierend auf verschiedenen Projekten auf Basis von Nginx (empfohlen)
Gemeinsame Login-Implementierung
oauth2 offenes Protokoll
1. Generieren Sie eine Autorisierungslinkadresse basierend auf der App-ID
2. Erhalten Sie den Autorisierungscode
3. Rufen Sie das AccessToken basierend auf dem Autorisierungscode ab
4. Erhalten Sie Benutzerinformationen basierend auf dem Autorisierungscode
Verteilte Lösungen
Nachteile herkömmlicher Sammelprotokolle
Verwenden Sie tail, um Protokolle auf jedem Server zu durchsuchen
Lösung
AOP Elk Kafka implementiert die verteilte Protokollsammlung
Warum Elch Kafka hinzufügen muss
Reduzieren Sie die Betriebs- und Wartungskosten für jede Logstash-Installation
Vorsichtsmaßnahmen
AOP speichert die gesammelten Protokolle in einer gleichzeitigen Warteschlange zwischen und übermittelt die Protokolle in einem asynchronen separaten Thread an Kafka.
Aggregiertes Zahlungsdesign
Zahlungsarchitekturprozess
Signaturmethode überprüfen
Asymmetrische RSA-Verschlüsselung
MD5
Rückrufmethode
Synchroner Rückruf
Nachdem die Drittanbieterzahlung erfolgreich war, wird sie in Form einer Zahlungsbrowser-Umleitung an den Händler weitergeleitet.
Asynchroner Rückruf
Bei Zahlungen von Drittanbietern werden Benachrichtigungen an Händler mithilfe einer Technologie gesendet, die HttpClient ähnelt
Designmuster
Strategiemuster
Vorlagenmethodenmuster
häufiges Problem
Wie synchrone Rückrufe und asynchrone Rückrufe die Schnittstellensicherheit gewährleisten
Der synchrone Rückruf springt in Form eines Browsers und verändert den Bestellstatus nicht.
Nachdem der asynchrone Rückruf die Signatur erfolgreich überprüft hat, achten Sie auf das idempotente Problem, um den Bestellstatus zu ändern.
So verhindern Sie, dass Benutzer wiederholt bezahlen
Die gleiche Bestellnummer wird vom Formular an die Drittanbieterzahlung übermittelt, und die Drittanbieterzahlung stellt die globale Eindeutigkeit basierend auf der Bestellnummer sicher.
Was soll ich tun, wenn die Zahlung des Benutzers erfolgreich ist, der Bestellstatus aber immer noch unbezahlt ist?
Dieses Phänomen ist normal. Durch die Idee der eventuellen Konsistenz können Sie die Alipay-Schnittstelle aktiv aufrufen, um abzufragen, ob die Bestellung bezahlt wurde.
So gehen Sie mit der Inkonsistenz zwischen dem Zahlungsbetrag des Benutzers und dem Bestellbetrag um
Beim asynchronen Rückruf wird anhand der Bestellung abgefragt, ob die tatsächliche Bestellnummer des Benutzers mit dem Zahlungsbetrag des Benutzers übereinstimmt.<br>Wenn sie inkonsistent sind, handelt es sich um eine abnormale Bestellung.
Welche Arten von Zahlungstabellen-Betragsfeldern sind geeignet?
Die direkte Speicherung ganzzahliger Typen kann später in Elemente umgewandelt werden
Dezimaltyp
So gehen Sie mit einer Bestellung um, die seit 30 Minuten Überstunden nicht bezahlt wurde
Basierend auf der MQ-Verzögerungswarteschlange implementiert (empfohlen)
1. Nachdem die Bestellung erfolgreich aufgegeben wurde, übermitteln Sie eine verzögerte Warteschlangennachricht an MQ
2. Wenn die Nachricht abläuft, wird sie in die Warteschlange für unzustellbare Nachrichten übertragen.
3. Der Verbraucher der Dead-Letter-Queue hört sich die Nachricht an und prüft, ob der Bestellstatus bezahlt ist.
Basierend auf einem abgelaufenen Redis-Schlüssel implementiert (nicht empfohlen)
1. Nachdem Sie die Bestellung erfolgreich aufgegeben haben, legen Sie einen 30-Minuten-Ablaufschlüssel für Redis fest.
2. Wenn der Kunde den Ablauf des Schlüssels überwacht, prüft er, ob der Bestellstatus bezahlt ist.
3. Um die Überwachung abgelaufener Schlüssel zu aktivieren, müssen Sie auf das Präfix achten und eine separate Redis-Bibliothek abonnieren.
häufiges Problem
Die Karte des Benutzers zahlt innerhalb von 30 Minuten. Wie kann die Konsistenz des Bestellstatus sichergestellt werden?
1. Stellen Sie den Timeout für die Umleitung von Alipay-Bestellungen auf 30 Minuten ein
2. Die Verzögerungswarteschlange ruft nach etwa 31 bis 35 Minuten aktiv die Alipay-Schnittstelle auf, um den Zahlungsstatus anhand der Bestellnummer zu überprüfen.
3. Erfolgt die Zahlung nach Aufruf der Alipay-Schnittstelle immer noch nicht, gilt die Bestellung als zeitaufwändig.
Design der Produkt-Service-Systemarchitektur
So erreichen Sie Widerstand gegen hohe Parallelität
Front-End-Schicht
Optimierung
Dynamische und statische Trennarchitektur
Statischer Ressourcenserver
dynamischer Ressourcenserver
Statische Ressourcenkomprimierung
Generieren Sie eine .min-Datei
CDN-Cache
Besuchen Sie nach dem Prinzip der Nähe
endgültige Wirkung
Bandbreitenübertragung reduzieren
Schnittstellenschicht
Optimierung
Optimierung der JVM-Parameter, um die Anzahl der GC-Recycling-STW-Probleme zu reduzieren
Behandeln Sie zeitaufwändige Vorgänge in Form von asynchroner Multithreading/MQ-Entkopplung
Verwenden Sie den Redis-Cache, um den Druck des DB-Zugriffs zu verringern
Erwägen Sie die Aufteilung von Tabellen und Datenbanken/Indexoptimierung für MySQL-Massendaten
endgültige Wirkung
Betriebs- und Wartungsebene
Verwenden Sie Docker oder K8S, um die Bereitstellung elastisch zu erweitern/zu verkleinern
JavaSE
Grundgrammatik
Art der Daten
Grundlegende Datentypen
Numerischer Typ
Ganzzahl (Byte, kurz, int, lang)
Gleitkommazahl (float,double)
Zeichen(char)
nicht numerischer Typ
Boolescher Wert
Referenzdatentyp
Klasse
Schnittstelle
Array[]
objektorientierte
Sammlungsrahmen
IO-Stream
Reflexionsmechanismus
Multithreading
JDBC
JavaWeb
Base
Servlet
JSP
rahmen
Frühling5
Beziehung zwischen Spring5 und SpringBoot
SpringBean-Injektionsmethode
SpringBean-Injektionsmethode
Vom parametrischen Konstruktor injizierte Eigenschaften
p-Namespace-Injektion
Fügen Sie Nullwerte und Sonderzeichen ein
Innere Bohnen einspritzen
Externe Bohnen einspritzen
Inject-Kaskadenzuweisung
Eigenschaften des Sammlungstyps einfügen
Frühlingsfabrikbohnen
SpringBean-Lebenszyklus
Schritt 1: Verwenden Sie die Reflexionstechnologie, um das Objekt zu initialisieren und den Konstruktor ohne Argumente aufzurufen
Schritt 2: Rufen Sie mithilfe von Reflection die Set-Methode auf, um den Eigenschaften Werte zuzuweisen.
Der dritte Schritt der Ausführung: Beans Postprozessor-Vormethode
Schritt 4: Rufen Sie die Init-Methode im Objekt auf
Schritt 5: Beans Postprozessor-Postmethode
Schritt 6: Zerstören Sie das Objekt und rufen Sie die Zerstörungsmethode auf
SpringBean-Bereich
Singleton-Objekt
Mehrere Instanzobjekte
Automatische SpringBean-Verkabelung
Externe SpringBean-Eigenschaftendatei
SpringBean-Anmerkungsformular
Startmethode für SpringBean-Annotationen
Annotations-Startfunktion von SpringBean
Konfiguration zum Scannen von SpringBean-Anmerkungen
Autowired- und Qualifier-Anmerkungen
@Ressourcennutzung
SpringBean AOP
AOP-Grundkonzepte
Die grundlegende Rolle von AOP
Statischer Proxy und dynamischer Proxy
Verwendung der @AspectJ-Annotation
Verwenden Sie aop, um Protokolle einheitlich zu drucken
SpringBean-Transaktionsoperationen
Klassifizierung von Transaktionen
Manuelle Transaktionen
Programmierangelegenheiten
Sieben Kommunikationsverhalten von Angelegenheiten
PROPAGATION_REQUIRED (Standard-Weitergabeverhalten)
Wenn im aktuellen Thread eine Transaktion vorhanden ist, treten Sie der aktuellen Transaktion bei
Wenn für den aktuellen Thread keine Transaktion vorhanden ist, erstellen Sie eine neue Transaktion
PROPAGATION_SUPPORTS
Wenn im aktuellen Thread eine Transaktion vorhanden ist, treten Sie der aktuellen Transaktion bei
Wenn im aktuellen Thread keine Transaktion vorhanden ist, wird sie auf eine Nicht-Transaktions-Weise ausgeführt.
PROPAGATION_MANDATORY
Wenn im aktuellen Thread eine Transaktion vorhanden ist, treten Sie der aktuellen Transaktion bei
Löst eine Ausnahme aus, wenn im aktuellen Thread eine Transaktion vorhanden ist
PROPAGATION_REQUIRES_NEW
Wenn im aktuellen Thread eine Transaktion vorhanden ist, wird die aktuelle Transaktion angehalten und eine neue Transaktion erstellt.
PROPAGATION_NOT_SUPPORTED
Wird immer auf nicht-transaktionale Weise ausgeführt
PROPAGATION_NEVER
Wird immer auf nicht-transaktionale Weise ausgeführt. Es wird eine Ausnahme ausgelöst, wenn im aktuellen Thread eine Transaktion vorhanden ist
PROPAGATION_NESTED
Wenn im aktuellen Thread eine Transaktion vorhanden ist, wird eine Transaktion verschachtelt
SpringMVC
Mybatis
Überwintern
Mikrodienste
SpringBoot2.0
Warum Sie das SpringBoot-Framework verwenden müssen
Kann Entwicklern helfen, Frameworks von Drittanbietern schnell zu integrieren (Prinzip: Maven-Abhängigkeitskapselung)
Entfernen Sie die XML-Konfiguration und verwenden Sie die Annotation vollständig (Prinzip: integrierte Annotationsmethode im Spring-System).
Kein externer Tomcat und kein interner Implementierungsserver erforderlich (Prinzip: Java-Sprache unterstützt eingebetteten Tomcat-Server)
Der Unterschied zwischen SpringBoot und SpringCloud
SpringCloud-Abhängigkeiten und SpringBoot-Komponenten
Verwenden Sie SpringMVC, um eine HTTP-Protokollschnittstelle zu schreiben
Spring Cloud ist ein vollständiges Microservice-Lösungsframework
Einführung in die SpringBoot-Abhängigkeitseinführung
spring-boot-start-parent,
Spring-Boot-Starter-Web
@RestController-Rolle
Alle Methoden des Controllers geben das JSON-Format zurück
SpringBoot-Startmethode
@EnableAutoConfiguration
@ComponentScan
@SpringBootApplication
Alle Klassen unter dem aktuellen Paket oder Unterpaketen können gescannt werden
SpringBoot integriert den statischen Ressourcenzugriff
Welches Template-Engine-Framework
Rendern Sie das Web, was sich positiv auf die SEO-Suche auswirkt
Integrieren Sie die FTL-Vorlagen-Engine
Integrieren Sie die Thymeleaf-Template-Engine
SpringBoot integriert Datenquellen
JdbcTemplate
mybatis
überwintern
SpringBoot integrierte Hot-Bereitstellung
Integrieren Sie Devtools-Tools
Implementierung des Klassenladers
Lombok integrieren
Konfigurationsdatei für die SpringBoot-Integration
Verwenden Sie die @value-Annotation, um Konfigurationsdateien zu lesen
Eigenschaften konvertieren das YML-Format
@ConfigurationProperties
Verwendung von Platzhaltern in der Konfigurationsdatei
Integrieren Sie verschiedene Konfigurationsdateien in mehrere Umgebungen
Ändern Sie Port und Kontextpfad
Integriertes SpringBoot-Protokoll-Framework
Wieder anmelden
log4j
Verwenden Sie aop, um Protokollinformationen einheitlich zu drucken
Geplante SpringBoot-Aufgaben
Integrieren Sie geplante Aufgaben mit der @Scheduled-Annotation
Zeitgesteuerte Integrationsaufgaben kombiniert mit Quartz-Ausdrücken
SpringBoot integriert asynchrones Multithreading
Achten Sie auf das @Async-Ungültigmachungsproblem
@Async integriert Thread-Pool
Integrieren Sie globale Catch-Ausnahmen
Packen Sie die Version und führen Sie sie aus
Projektwerkzeuge
Docker
Basiskonzept
Warum müssen Sie Docker verwenden?
Vorteile der Verwendung von Docker
Der Unterschied zwischen Containern und virtuellen Maschinen
Umgebungsinstallation
Installieren Sie Docker in einer Linux-Umgebung
Installieren Sie Docker in der Win-Umgebung
Drei Hauptelemente
Bilddatei
Container
Lagerhaus
Spiegelprinzip
Docker-Download-Image-Prinzip
Prinzip des Docker-Image-Ladens
bootfs
rootfs
Union fs
Cloudbeschleunigte Bildkonfiguration
Alibaba Cloud beschleunigtes Image
Huawei Cloud Accelerated Image
HKUST-Beschleunigungsspiegel
Allgemeine Docker-Befehle
docker --help (Hilfebefehl)
docker --version (Version anzeigen)
Docker-Bilder (Bilder ansehen)
Docker-Suche (Suchbild)
Docker Pull (Bild herunterladen)
Latest -----Tag neueste Version der Bilddatei
Docker-Container
Docker Run (Container starten)
Docker Start startet die Container-ID
Docker-Stopp-Container-ID
Docker-RM-Container-ID
docker exec -it [CONTAINER ID] bash (Container eingeben)
Docker-Protokolle – seit 30 m CONTAINER_ID (Containerprotokolle anzeigen)
Docker Commit (in eine Bilddatei basierend auf dem aktuellen Container umgewandelt)
Docker-Datenvolumen -v
Installieren Sie häufig verwendete Software
Kater
docker run -p 8081:8080 -d tomcat:8
Nginx
docker run --name nginx81 -d -p 81:80
MySQL
docker create --name mysql3308 -e MYSQL_ROOT_PASSWORD=root -p 3308:3306 mysql:5.7
DockerFile-Analyse
DockerFile-Schreibspezifikationen
DockerFile-Direktive
Erstellen Sie ein Springboot-Projekt basierend auf Dockerfile
Docker Compose
Verfassen Sie allgemeine Befehle
docker-compose -h
Docker-Komponieren
Docker-Compose nach unten
Docker-Compose-Protokolle
Docker-Compose-Pull
dokcer-compose-Konfiguration
Docker-Compose-Neustart
Docker-Compose-Start
Erstellen Sie eine Vorlagendatei
Stellen Sie das SpringBoot MySQL Nginx-Microservice-Projekt bereit
Verwendung des Docker-Visualisierungstools
Träger
DockerUI
k8s
meta-natives Konzept
Mikrodienste
Erholsame Kommunikation zwischen Anwendungen
Unabhängig entfaltbar/elastisch erweiterbar und verkleinerbar
Entwickler
Automatisierte Release-Pipeline, Ci/CD-Tools
Stellen Sie die Produktionsumgebung schnell bereit
Integration von Entwicklung und Betrieb und Wartung
Kontinuierliche Lieferung
Häufige Veröffentlichungen, schnelle Lieferung, schnelles Feedback und geringere Veröffentlichungsrisiken
Containerisierung
Der beste Carrier für Microservices
Designmuster
Proxy-Modus