Überblick
Als ich bei Netease interviewte, stellte mir der Interviewer eine Frage und sagte
Was kann ich nach dem Aufgeben einer Bestellung tun, wenn der Benutzer die Bestellung nicht bezahlt und die Bestellung stornieren muss?
Meine Antwort war es zu diesem Zeitpunkt, eine zeitgesteuerte Aufgabe zu verwenden, um die DB -Tabelle zu scannen. Der Interviewer war nicht sehr zufrieden und fragte:
Gibt es eine andere Möglichkeit, zeitgesteuerte Aufgaben zu verwenden, um genaue Echtzeit-Benachrichtigungen zu erzielen?
Meine Antwort zu dieser Zeit war:
Sie können eine Warteschlange verwenden. Nachdem die Bestellung aufgegeben wurde, wird eine Nachricht an die Warteschlange gesendet und die Ablaufzeit angegeben. Sobald die Zeit eintrifft, wird die Rückrufschnittstelle ausgeführt.
Nachdem der Interviewer zugehört hatte, hörte er auf zu fragen. Eigentlich war meine Idee zu dieser Zeit richtig, aber ich war nicht sehr professionell. Das professionelle Sprichwort ist, verzögerte Nachrichten zu verwenden.
Tatsächlich gibt es in der Tat ein Problem bei der Verwendung zeitgesteuerter Aufgaben. Das ursprüngliche Geschäftssystem hofft, dass die Bestellung sofort storniert und das Produktinventar veröffentlicht wird, wenn die Bestellung nicht in 10 Minuten bezahlt wird. Sobald das Datenvolumen groß ist, wird die Zeit für die Erlangung unbezahlter Auftragsdaten verlängert. Einige Bestellungen werden nach 10 Minuten storniert, was möglicherweise 15 Minuten, 20 Minuten usw. betragen kann. Auf diese Weise wird das Inventar nicht rechtzeitig freigegeben und wirkt sich auch auf die ungerade Zahl aus. Mithilfe von Verzögerungsnachrichten kann der Auftragsabbreitungsvorgang theoretisch gemäß der festgelegten Zeit durchgeführt werden.
Derzeit beziehen sich die meisten Artikel im Internet zur Verwendung von Rabbitmq zur Implementierung verzögerter Nachrichten darin, wie die tote Briefwarteschlange von Rabbitmq zur Implementierung verwendet werden kann. Die Implementierungslösung sieht sehr kompliziert aus und wird mit der ursprünglichen Rabbitmq -Client -API implementiert, die noch mehr ausführlicher ist.
Spring Boot hat die Rabbitmq -Client -API eingeschlossen, die viel einfacher zu verwenden ist. Hier finden Sie eine detaillierte Einführung in die Verwendung des Plug-In- und Spring-Starts von Rabbitmq_Delayed_Message_Exchange, um verzögerte Nachrichten zu implementieren.
Softwarevorbereitung
Erlang
Die in diesem Artikel verwendete Version lautet: Erlang 20.3
Rabbitmq
Dieser Artikel verwendet die Fensterversion von Rabbitmq. Die Versionsnummer lautet: 3.7.4
RABBITMQ_DELAYED_MESSAGE_EXchange Plugin
Plugin-Download-Adresse: http://www.rabbitmq.com/community-plugins.html
Nach dem Öffnen der URL, CTRL + F und RABBITMQ_DELAYED_MESSAGE_EXCHANGE.
Denken Sie daran, Sie müssen die Versionsnummer auswählen. Da ich Rabbitmq 3.7.4 verwende, muss das entsprechende Rabbitmq_Delayed_Message_Exchange-Plug-In auch 3.7.x.
Wenn Sie nicht die richtige Version auswählen, werden Sie bei der Verwendung verzögerter Nachrichten auf verschiedene seltsame Probleme stoßen, und es gibt keine Lösung im Internet. Ich hatte die ganze Nacht wegen dieses Problems zu kämpfen. Bitte denken Sie daran, die richtige Plug-in-Version auszuwählen.
Platzieren Sie nach dem Herunterladen des Plugins das Plugins -Verzeichnis im Verzeichnis von RabbitMQ -Installation und starten Sie das Plugin mit dem folgenden Befehl:
Rabbitmq-Plugins aktivieren Rabbitmq_Delayed_Message_Exchange
Wenn das Startup erfolgreich ist, wird die folgende Nachricht angezeigt:
Die folgenden Plugins wurden aktiviert: RABBITMQ_DELAYED_MESSAGE_EXchange
Denken Sie daran, dass das Plug-in erfolgreich gestartet wurde, denken Sie daran, Rabbitmq neu zu starten, damit dies wirksam wird.
Integrierter Rabbitmq
Dies ist sehr einfach. Fügen Sie es einfach in die Datei pom.xml des Maven -Projekts hinzu
<Depopenty> <gruppe> org.springFramework.boot </Groupid> <artifactId> Spring-Boot-Starter-Amqp </artifactid> </abhängig>
Ich verwende 2.0.1.Release für Spring Start.
Fügen Sie als nächstes die Redis -Konfiguration in die Datei application.Properties hinzu:
Spring.Rabbitmq.host = 127.0.0.1Spring.Rabbitmq.port = 5672Spring.Rabbitmq.Unername = Guestspring.rabbitmq.Password = guden
Definieren Sie ConnectionFactory und Rabbittemplate
Es ist auch sehr einfach, der Code ist wie folgt:
Paket com.mq.rabbitmq; import org.springframework.amqp.rabbit.connection.cachingConnectionFactory; org.springframework.boot.context.properties.configurationProperties; import org.springFramework.context.annotation.bean; privater Int -Port; privater String -Benutzername; privates Zeichenfolgenkennwort; @Bean public ConnectionFactory ConnectionFactory () {CachingConnectionFactory CachingConnectionFactory = new CachingConnectionFactory (Host, Port); CachingConnectionFactory.Setusername (Benutzername); CachingConnectionFactory.SetPassword (Passwort); CachingConnectionFactory.setVirtualHost ("/"); CachingConnectionFactory.SetPublisherConFirms (true); return cachingConnectionFactory; } @Bean Public Rabbittemplate Rabbittemplate () {Rabbittemplate Rabbittemplate = new Rabbittemplate (ConnectionFactory ()); Return Rabbittemplate; } public String gethost () {return host; } public void Sethost (String Host) {this.host = host; } public int getPort () {return port; } public void setport (int port) {this.port = port; } public String getUnername () {return userername; } public void setUnername (String -Benutzername) {this.username = userername; } public String getPassword () {Kennwort zurückgeben; } public void setPassword (String -Passwort) {this.password = password; }}Austausch- und Warteschlangenkonfiguration
Paket com.mq.rabbitmq; import org.springframework.amqp.core.*; import org.springframework.context.annotation.bean; {@Bean public CustOMExChange DelayExchange () {map <String, Object> args = new HashMap <> (); args.put ("X-Delayed-Typ", "Direct"); NEUE CUSTOMEXChange zurückgeben ("test_exchange", "x-delayed-message", wahr, falsch, args); } @Bean public queue queue () {queue queue = new Queue ("test_queue_1", true); Warteschlange zurückgeben; } @Bean public binding binding () {return bindingBuilder.bind (queue ()). To (delayExchange ()). Mit ("test_queue_1"). Noargs (); }}Es sollte hier angemerkt werden, dass Customexchange verwendet wird, nicht direktexchange, und die Art der Customexchange muss X-Delayed-Message sein.
Nachrichtensenden implementieren
Paket com.mq.rabbitmq; import org.springframework.amqp.amqpexception; import org.springframework.amqp.core.message import org.springframework.amqp.core.messagepostprozessor; org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.Service; Import Java.Text.SimpledateFormat; importieren java.util.date; public void sendmsg (String queueName, String msg) {SimpleDateFormat SDF = new SimpleDateFormat ("yyyy-mm-dd hh: mm: ss"); System.out.println ("Nachricht senden Zeit:"+SDF.Format (neues Datum ())); Rabbittemplate.ConvertandSend ("test_exchange", queueName, msg, neuer messagePostProcessor () {@Override public message postProcessMessage (Message Message) löst amqpexception {message.getMessageProperties (). }}Beachten Sie, dass beim Senden ein Kopfball hinzugefügt werden muss
X-Delay
Die Verzögerungszeit, die ich hier festgelegt habe, beträgt 3 Sekunden.
Nachrichtenverbraucher
Paket com.mq.rabbitmq; import org.springframework.amqp.rabbit.annotation.rabbitHandler; java.util.date; @Componentpublic class messageeceiver {@rabbitListener (queues = "test_queue_1") public void recence (String msg) {simpleDateFormat sdf = new SimpleDateFormat ("YYYY-MM-DD HH: MM: SSS SSS"); System.out.println ("Nachrichtenempfangszeit:"+SDF.Format (neues Datum ())); System.out.println ("Empfangene Nachricht:"+msg); }}Führen Sie das Spring -Boot -Programm aus und senden Sie Nachrichten
Führen Sie das Spring Boot -Programm direkt in der Hauptmethode aus, und Spring Boot analysiert automatisch die MessageCeiver -Klasse.
Als nächstes führen Sie JUNIT einfach aus, um die Schnittstelle auszuführen, die die Nachricht sendet.
Paket com.mq.rabbitmq; import org.junit.test; import org.junit.runner.runwith; import org.springframework.bean.factory.annotation.autowired; org.springFramework.test.context.junit4.springrunner; @runwith (Springrunner.class) @springBoottestPublic Class RabbitMqapplicationTests {@autowired private messyserviceMpl; @Test public void send () {messageService.sendmsg ("test_queue_1", "Hallo, ich bin verzögerte msg"); }} Nach dem Laufen sehen Sie die folgenden Informationen:
Meldungszeitzeit: 2018-05-03 12:44:53
Nach 3 Sekunden wird die Spring -Startkonsole ausgegeben:
Meldungsempfangszeit: 2018-05-03 12:44:56
Empfangene Nachricht: Hallo, ich bin verzögerte msg
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.