Unsere Freunde sollten genug über Message Middleware MQ gehört haben, wie zum Beispiel: RabbitMQ, RocketMQ, Kafka usw. Die Vorteile der Einführung von Middleware können dazu beitragen, hoher Parallelität, Peaking und Geschäftsentkopplung entgegenzuwirken.
Wie oben gezeigt:
(1) Der Bestelldienst übermittelt Nachrichten an die MQ-Middleware. (2) Der Logistikdienst überwacht die MQ-Middleware-Nachrichten auf Verbrauch.
Lassen Sie uns in diesem Artikel besprechen, wie der Bestelldienst sichergestellt werden kann Am Beispiel von RabbitMQ wird die Nachricht erfolgreich an die MQ-Middleware übermittelt.
Meine Freunde haben möglicherweise einige Fragen dazu. Wenn der Bestelldienst den Nachrichtendienst initiiert, bedeutet das nicht Erfolg, wenn die Rücksendung erfolgreich ist? Zum Beispiel der folgende Pseudocode:
Im obigen Code werden Nachrichten im Allgemeinen so gesendet. Glauben Sie, dass es ein Problem gibt?
Lassen Sie uns unten über ein Szenario sprechen. Was passiert, wenn der MQ-Server plötzlich ausfällt? Sind alle Nachrichten unseres Bestellservices verschwunden? Ja, im Allgemeinen speichert die MQ-Middleware Nachrichten im Speicher, um den Durchsatz des Systems zu verbessern. Wenn keine andere Verarbeitung erfolgt, gehen alle Nachrichten verloren, sobald der MQ-Server ausfällt. Dies wird vom Unternehmen nicht zugelassen und wird große Auswirkungen haben.
Ich weiß, dass es beim Senden einer Nachricht einen dauerhaften Parameter gibt, der auf „true“ gesetzt werden kann , es wird Persistenz.
In diesem Fall werden die Nachrichten auch bei einem Ausfall des MQ-Servers nach dem Neustart in der Festplattendatei gespeichert, sodass sie nicht verloren gehen. Ja, dadurch wird sichergestellt, dass die Nachricht mit einer gewissen Wahrscheinlichkeit nicht verloren geht.
Aber es wird ein Szenario geben, in dem die Nachricht gerade im MQ-Speicher gespeichert wurde, aber bevor sie in der Festplattendatei aktualisiert werden kann, stürzt sie plötzlich ab. (Verdammt, das wird in so kurzer Zeit passieren. Die Wahrscheinlichkeit ist zu gering.) Dieses Szenario wird im Prozess der kontinuierlichen Nachrichtenzustellung in großem Maßstab sehr häufig auftreten.
Was tun? Wie können wir sicherstellen, dass es auf der Festplatte gespeichert bleibt?
Das obige Problem entsteht, weil uns niemand sagt, ob Persistenz erfolgreich ist. Glücklicherweise verfügen viele MQs über Rückrufbenachrichtigungsfunktionen und RabbitMQ verfügt über einen Bestätigungsmechanismus, der uns benachrichtigt, ob die Persistenz erfolgreich ist.
Prinzip des Bestätigungsmechanismus:
Der obige Pseudocode verfügt über zwei Möglichkeiten, Nachrichten zu verarbeiten, nämlich Bestätigungsrückruf und Nack-Rückruf.(1) Der Nachrichtenproduzent sendet die Nachricht an MQ. Wenn der Empfang erfolgreich ist, sendet MQ eine Bestätigungsnachricht an den Produzenten zurück ist nicht erfolgreich, MQ Eine Nack-Nachricht wird an den Produzenten zurückgegeben
Ist dadurch sichergestellt, dass nicht 100 % der Nachrichten verloren gehen?
Werfen wir einen Blick auf den Bestätigungsmechanismus? Stellen Sie sich vor, jedes Mal, wenn unser Produzent eine Nachricht sendet, muss MQ auf der Festplatte gespeichert werden und dann einen Bestätigungs- oder Nack-Rückruf initiieren. In diesem Fall ist der Durchsatz unseres MQ sehr gering, da die Nachricht jedes Mal auf der Festplatte gespeichert werden muss. Das Schreiben auf die Festplatte ist sehr langsam. Dies ist in Szenarien mit hoher Parallelität nicht akzeptabel und der Durchsatz ist zu gering.
Die eigentliche Implementierung der persistenten MQ-Festplatte erfolgt über einen bestimmten Mechanismus. Wenn beispielsweise Tausende von Nachrichten vorhanden sind, werden diese auf einmal geleert. Anstatt die Festplatte jedes Mal zu leeren, wenn eine Nachricht eingeht.
Der Bestätigungsmechanismus ist also tatsächlich ein asynchroner Abhörmechanismus, der den hohen Durchsatz des Systems sicherstellen soll. Dies bedeutet, dass die Nachricht nicht zu 100 % verloren geht, denn selbst wenn der Bestätigungsmechanismus hinzugefügt wird , die Nachricht befindet sich immer noch im MQ-Speicher. Der Computer ist ohne Flashen auf die Festplatte abgestürzt und kann immer noch nicht bearbeitet werden.
Nachdem ich so viel gesagt habe, kann ich es immer noch nicht garantieren. Was soll ich also tun? ? ?
Tatsächlich ist der wesentliche Grund, dass es unmöglich ist, festzustellen, ob sie persistiert? Können wir die Botschaft also selbst dauerhaft machen? Die Antwort lautet: Ja, unser Plan wird sich weiterentwickeln.
Der Prozess im obigen Bild:
(1) Vor der Übermittlung der Nachricht überträgt der Bestelldienstersteller die Nachricht zunächst an Redis oder Redis, um eine hohe Leistung zu erzielen. Der Status der Nachricht ist Wird gesendet.
(2) Wurde die Überwachungsnachricht des Bestätigungsmechanismus erfolgreich gesendet? Wenn die Bestätigung erfolgreich ist, löschen Sie diese Nachricht in Redis.
(3) Wenn Nack fehlschlägt, können Sie wählen, ob Sie die Nachricht je nach Ihrem eigenen Unternehmen erneut senden möchten. Abhängig von Ihrer geschäftlichen Entscheidung können Sie diese Nachricht auch löschen.
(4) Hier wird eine geplante Aufgabe hinzugefügt, um die Nachricht nach einer bestimmten Zeitspanne abzurufen. Der Nachrichtenstatus wird immer noch gesendet. Dieser Status zeigt an, dass der Bestelldienst die Bestätigungs-Erfolgsnachricht nicht erhalten hat.
(5) Geplante Aufgaben liefern kompensatorische Nachrichten. Wenn zu diesem Zeitpunkt die MQ-Rückrufbestätigung erfolgreich empfangen wird, wird die Nachricht in Redis gelöscht.
Dieser Mechanismus ist eigentlich ein Kompensationsmechanismus. Es ist mir egal, ob MQ ihn tatsächlich empfängt. Solange der Nachrichtenstatus in meinem Redis [Sendet] lautet, bedeutet dies, dass die Nachricht nicht erfolgreich korrekt zugestellt wurde. Starten Sie dann die geplante Aufgabe zur Überwachung und Einleitung der Entschädigungslieferung.
Natürlich können wir auch eine Kompensationsnummer für die geplante Aufgabe hinzufügen und immer noch keine Bestätigungsnachricht erhalten, dann setzen Sie den Status der Nachricht direkt auf [Fehlgeschlagen] und lassen Sie die Leute manuell überprüfen, warum ?
In diesem Fall ist die Lösung perfekter und stellt sicher, dass 100 % der Nachrichten nicht verloren gehen (dabei ist der Festplattenausfall natürlich nicht berücksichtigt, sodass eine Master-Slave-Lösung verwendet werden kann).
Mit dieser Lösung ist es jedoch möglich, dieselbe Nachricht mehrmals zu senden. Es ist sehr wahrscheinlich, dass MQ die Nachricht bereits empfangen hat, beim Rückruf der Bestätigungsnachricht jedoch ein Netzwerkfehler aufgetreten ist, der Produzent jedoch nicht Erhalte es.
Dann müssen wir von Verbrauchern verlangen, beim Konsum auf Idempotenz zu achten!
Lassen Sie uns zunächst verstehen, was Idempotenz ist. In verteilten Anwendungen ist Idempotenz sehr wichtig. Das heißt, wenn ein Unternehmen unter denselben Bedingungen betrieben wird, ist das Ergebnis dasselbe, unabhängig davon, wie oft es ausgeführt wird.
Warum gibt es ein Szenario wie idempotent? Denn in großen Systemen werden sie alle verteilt eingesetzt. Beispielsweise können Auftragsgeschäft und Lagergeschäft unabhängig voneinander eingesetzt werden und sind separate Dienste. Wenn ein Benutzer eine Bestellung aufgibt, werden der Bestellservice und der Lagerservice aufgerufen.
Aufgrund der verteilten Bereitstellung ist es sehr wahrscheinlich, dass der Aufruf des Bestellservices aus Netzwerk- und anderen Gründen fehlschlägt. Tatsächlich wurde der Inventarservice jedoch verarbeitet, bei der Verarbeitung ist jedoch eine Ausnahme aufgetreten Das Ergebnis wurde an den Bestellservice zurückgegeben. Zu diesem Zeitpunkt erstellt das System im Allgemeinen einen Vergütungsplan, d. h. der Bestelldienst ruft dann den Lagerdienst an und der Lagerbestand wird um 1 reduziert.
Es liegt tatsächlich ein Problem vor, der letzte Anruf wurde um 1 reduziert, aber der Bestellservice hat das Bearbeitungsergebnis nicht erhalten. Jetzt wird es erneut aufgerufen und muss um 1 reduziert werden. Dies entspricht nicht dem Geschäft und ist ein zusätzlicher Abzug.
Das Konzept der Idempotenz besteht darin, dass das Verarbeitungsergebnis dasselbe ist, egal wie oft der Inventardienst unter denselben Bedingungen aufgerufen wird. Nur so kann die Durchführbarkeit des Vergütungsplans sichergestellt werden. 6.2. Optimistisches Sperrschema Führen Sie die Bestandsaufnahme durch und bringen Sie dann diese Versionsnummer mit. Lassen Sie uns das klären. Als wir die Inventur zum ersten Mal durchführten, bekamen wir Version 1, und als wir den Inventurservice anriefen, gab es ein Problem, als wir zum Bestellservice zurückkehrten Wenn der Bestelldienst als Version übergeben wird und die obige SQL-Anweisung erneut ausgeführt wird, wird sie nicht ausgeführt, da die Version auf 2 geändert wurde. Dies stellt sicher, dass es, egal wie oft es aufgerufen wird, nur einmal tatsächlich verarbeitet wird.
Das Prinzip besteht darin, den Datenbank-Primärschlüssel zu verwenden, um Duplikate zu entfernen. Geben Sie nach Abschluss des Geschäfts die Primärschlüssel-ID ein ist der einzige Primärschlüssel der Geschäftstabelle, z. B. die Produkt-ID
Der Fingerabdruckcode dient zur Unterscheidung des Codes für jeden normalen Vorgang. Der Fingerabdruckcode wird für jeden Vorgang generiert. Es kann die Methode Zeitstempel + Geschäftsnummer verwendet werden.
Die obige SQL-Anweisung:
Wenn der Rückgabewert 0 ist, bedeutet dies, dass nach dem Geschäftsvorgang kein Vorgang durchgeführt wurde. Sie können ihn in t_check (eindeutige ID + Fingerabdruckcode) einfügen
Rückgabewert, wenn er größer als 0 ist. Nach der Operation direkt zurückkehren
Vorteile: Einfache Implementierung
Nachteile: Datenbankengpass bei hoher Parallelität
Lösung: Datenbanken und Tabellen nach ID für Algorithmus-Routing aufteilen
Verwenden Sie die atomare Operation von Redis, um den Abschluss der Operation zu markieren. Diese Leistung ist besser. Aber es wird einige Probleme geben.
Erstens: Müssen wir die Geschäftsergebnisse in der Datenbank speichern? Wenn ja, besteht das Hauptproblem, das es zu lösen gilt, darin, wie man Atomizität in Datenbank- und Redis-Operationen erreicht?
Das bedeutet, dass der Bestand um 1 reduziert wird, aber was soll ich tun, wenn der Redis-Vorgang nach Abschluss der Markierung fehlschlägt? Das heißt, wir müssen sicherstellen, dass die Datenbanklöschung und die Redis-Operation entweder erfolgreich sind oder fehlschlagen. Zweitens: Wenn die Datenbank nicht gelöscht wird, wird alles im Cache gespeichert. Wie wird die geplante Synchronisierungsstrategie festgelegt?
Dies bedeutet, dass der Bestand um 1 reduziert wird und der Redis-Vorgang nicht direkt ausgeführt wird, um die Markierung abzuschließen. Anschließend wird ein weiterer Synchronisierungsdienst verwendet, um den Bestand zu löschen , und wie man die Synchronisationsstrategie festlegt
Das obige ist der detaillierte Inhalt von[Interview] Wie kann eine 100 % erfolgreiche Zustellung von Nachrichten sichergestellt werden? Wie kann die Nachrichten-Idempotenz sichergestellt werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!