In der Microservice -Architektur teilen wir ein Projekt in viele unabhängige Module auf, die durch Remote -Anrufe zusammenarbeiten. Bei hoher Parallelität führt jedoch die Zunahme der Anzahl der Kommunikation zu einer Erhöhung der gesamten Kommunikationszeit. Gleichzeitig sind auch die Ressourcen des Thread -Pools begrenzt. Eine hohe Parallelitätsumgebung führt zu einer großen Anzahl von Fäden in einem Wartezustand, was zu Verzögerungen bei der Antwort führt. Um diese Probleme zu lösen, müssen wir die Anfrage von hystrix verstehen.
Das Verschmelzung in hystrix besteht darin, einen Merge -Prozessor zu verwenden, um aufeinanderfolgende Anfragen zu verschmelzen, die vom gleichen Dienst in eine Bearbeitungserfassung initiiert wurden (das Zeitfenster für diese kontinuierlichen Anforderungen beträgt standardmäßig 10 ms). Eine der Kernklassen, die an diesem Prozess beteiligt sind, ist der HystrixCollapser, OK. Schauen wir uns anschließend an, wie die Hystrix -Anfrage implementiert werden kann.
Serviceanbieterschnittstelle
Ich muss zwei Schnittstellen im Dienstanbieter zur Verfügung stellen, damit die Service -Verbraucher wie folgt anrufen können:
@RequestMapping ("/getbook6") Public List <Book> book6 (String -IDs) { System.out.println("ids>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 33, "Hu Shi", "keine"); Literatur Publishing House 2 "); Rückgabebuch;}Die erste Schnittstelle ist eine Stapelschnittstelle und die zweite Schnittstelle ist eine Schnittstelle, die eine einzige Anforderung abwickelt. In der Batch -Schnittstelle beträgt das vom Service Consumer gesendete IDS -Parameterformat 1, 2, 3, 4 ... dieses Format. Unter normalen Umständen müssen wir die entsprechenden Daten basierend auf den IDs abfragen und sie dann in einen Satz zusammenstellen, um zurückzukehren. Aus Gründen der einfachen Verarbeitung werde ich denselben Datensatz zurückgeben, unabhängig von der Art von Anfrage. Die Schnittstelle zur Verarbeitung einer einzelnen Anforderung ist relativ einfach, daher werde ich sie nicht wiederholen.
Verbraucher dienen
OK, nachdem der Dienstanbieter damit umgegangen ist, schauen wir uns an, wie die Serviceverbraucher damit umgehen sollten.
Bookservice
Fügen Sie zunächst zwei Methoden zum BookService hinzu, um die vom Dienstanbieter bereitgestellte Schnittstelle wie folgt aufzurufen:
public book test8 (long id) {return rastTemplate.getForObject ("http: // hello-service/getbook6/{1}", book.class, id);} publiclist <Book> test9 (LIST <Lang> ids) {system.out.println ("test9 ----------- Thread.currentThread (). GetName ()); Book [] books = rastTemplate.getForObject ("http: // hello-service/getbook6? Ids = {1}", book []. Class, stringutils.join (ids, ",")); return Arrays.aslist (Bücher);}Test8 wird verwendet, um die Schnittstelle aufzurufen, die eine einzelne ID bietet. Test9 wird verwendet, um die Schnittstelle, die die Batch -Verarbeitung zu erhalten, aufzurufen. In Test9 drucke ich den Thread aus, in dem Test9 ausgeführt wird, um uns zu erleichtern, die Ausführungsergebnisse zu beobachten. Wenn der Rückgabewert in RestTemplate eine Sammlung ist, müssen wir sie zuerst mit einem Array erhalten und sie dann in eine Sammlung umwandeln (vielleicht gibt es andere Methoden, Freunde haben bessere Vorschläge zu machen).
BookbatchCommand
OK, nach der Methode in BookService können wir einen BookbatchCommand erstellen, der wie folgt ein Batch -Befehl ist:
public class bookbatchCommand erweitert hystrixCommand <list <book >> {private list <long> ids; privates Bookservice BookService; public bookbatchCommand (Liste <Long> ids, bodeService bodeService) {super (setzter.withgroupkey (hystrixcommandgroupkey.factory.askey ("collapsinggroup") .Andcommandkey (hystrixcommandkey.askey.askey ("collapsingSy")); this.ids = ids; this.bookService = bodeService; } @Override Protected List <Book> Run () löst Ausnahme aus {return bookeservice.test9 (ids); }}Diese Klasse ähnelt tatsächlich der Klasse, die wir im vorherigen Blog eingeführt haben. Sie werden beide von hystrixCommand geerbt und werden verwendet, um fusionierte Anforderungen zu verarbeiten und die Test9 -Methode in BookService in der Run -Methode aufzurufen.
BookCollapeSecommand
Als nächstes müssen wir BookCollapeSecommand erstellen, die von HystrixCollapser geerbt wurden, um Anforderungsverführungen zu implementieren. wie folgt:
öffentliche Klasse bookCollapeSecommand erweitert HystrixCollapseer <List <Book>, Buch, Long> {private BookService BookService; private lange Ausweis; public bookCollapeSecommand (BookService BookService, Long ID) {Super (Setter.askey.askey (hystrixcollapserKey.factory.askey ("bookCollapeSecommand"). AndcollapserPropertiesDefaults (hystrixCollapserProperties))). this.bookService = bodeService; this.id = id; } @Override public Long getRequestargument () {return id; } @Override Protected hystrixCommand <list <book >> createCommand (Sammlung <collapsequest <book, long >> collapsequests) {list <Long> ids = new ArrayList <> (collapsedrequests.size ()); ids.addall (collapsedRequests.stream (). map (collapsequest :: getArgument) .Collect (Sammler.Tolist ()); BookbatchCommand bookbatchCommand = new bookBatchCommand (IDS, BookService); return bookbatchCommand; } @Override Protected void MapResponSetorequests (Liste <Book> batchResponse, Sammlung <Collapsequest <book, long >> collapsedRequests) {System.out.println ("MapResponSetorequests"); int count = 0; für (collapsequest <book, long> collapsequest: collapsedRequests) {book book = batchResponse.get (count ++); CollapsedRequest.SetResponse (Buch); }}}In Bezug auf diese Klasse werde ich die folgenden Punkte sagen:
1. In der Konstruktionsmethode setzen wir das Anforderungszeitfenster auf 100 ms, dh die Anfragen mit dem Anforderungszeitintervall innerhalb von 100 ms werden in eine Anfrage zusammengefasst.
2. Die Methode createCommand wird hauptsächlich zum Zusammenführen von Anforderungen verwendet, die IDs jeder einzelnen Anforderung hier abrufen, diese einzelnen IDs in eine Sammlung einfügen und dann ein BuchbatchCommand -Objekt erstellen und dieses Objekt verwenden, um eine Batch -Anforderung zu initiieren.
3. Die MapResponSetorequests -Methode wird hauptsächlich verwendet, um das Anforderungsergebnis für jede Anforderung festzulegen. Der erste Parameter dieser Methode repräsentiert das Ergebnis der Stapelanforderung, und der zweite Parameter CollapsedRequests repräsentiert jede zusammengeführte Anforderung. Anschließend setzen wir das Anfrageergebnis für CollapsedRequests, indem wir BatchResponse durchqueren.
OK, nachdem all diese Vorgänge abgeschlossen sind, können wir es testen.
prüfen
Wir erstellen eine Zugriffsoberfläche auf der Service -Verbraucherseite, um die Merge -Anfrage zu testen. Die Testoberfläche lautet wie folgt:
@RequestMapping ("/test7")@responseBodypublic void test7 () löst ExecutionException, InterruptedException {hystrixRequestContext context = hystrixRequestContext.initializeContext () aus; BookCollapeSecommand bc1 = new BookCollapeSecommand (BookService, 1L); BookCollapeSecommand bc2 = new BookCollapeScommand (BookService, 2L); BookCollapeSecommand bc3 = new BookCollapeSecommand (BookService, 3L); BookCollapeSecommand bc4 = new BookCollapeScommand (BookService, 4L); Future <Book> q1 = bc1.queue (); Future <Book> q2 = bc2.queue (); Future <Book> q3 = bc3.queue (); Buchbuch1 = q1.get (); Book book2 = q2.get (); Buchbuch3 = q3.get (); Thread.sleep (3000); Future <Book> q4 = bc4.queue (); Book book4 = q4.get (); System.out.println ("book1 >>>"+book1); System.out.println ("book2 >>>"+book2); System.out.println ("Buch 3 >>>"+book3); System.out.println ("book4 >>>"+book4); context.close ();}In Bezug auf diese Testoberfläche sagte ich die folgenden zwei Punkte:
1. Erstens müssen Sie den hystrixRequestContext initialisieren
2. Erstellen Sie eine Instanz der BuchkollapeSecommand -Klasse, um eine Anfrage zu initiieren, zuerst 3 Anfragen zu senden, dann 3 Sekunden lang schlafen und dann eine Anfrage einleiten. Auf diese Weise werden die ersten 3 Anfragen in eine Anfrage zusammengefasst. Die vierte Anfrage wird nicht zusammengeführt, da das Intervall zwischen ihnen relativ lang ist, aber einen Thread erstellt, um ihn separat zu verarbeiten.
Ok, schauen wir uns die Ausführungsergebnisse wie folgt an:
Die Anfrage "Merge" wird durch Annotation implementiert
OK, die obige Anfrage -Zusammenführungsmethode ist ein wenig problematisch zu schreiben. Wir können Anmerkungen verwenden, um diese Funktion eleganter zu implementieren. Fügen Sie zunächst zwei Methoden in BookService hinzu, wie folgt:
@HystrixCollapser(batchMethod = "test11",collapserProperties = {@HystrixProperty(name ="timerDelayInMilliseconds",value = "100")})public Future<Book> test10(Long id) { return null;}@HystrixCommandpublic List<Book> test11(List<Long> ids) { System.out.println ("test9 ----------"+ids+"thread.currentThread (). GetName ():"+thread.currentThread (). GetName ()); Book [] books = rastTemplate.getForObject ("http: // hello-service/getbook6? Ids = {1}", book []. Class, stringutils.join (ids, ",")); return Arrays.aslist (Bücher);}Fügen Sie die Annotation von @hyStrixCollapser hinzu, um die Anforderungsverschmelzung in der Test10 -Methode zu implementieren. Verwenden Sie das BatchMethod -Attribut, um die Verarbeitungsmethode nach der Anforderung für den Zusammenschluss anzugeben, und das Attribut collapserProperties, um andere Attribute anzugeben.
OK, nachdem Sie es in BookService geschrieben haben, rufen Sie es einfach direkt wie folgt an:
@RequestMapping ("/test8")@responseBodypublic void test8 () löscht ExecutionException, InterruptedException {hystrixRequestContext context = hystrixRequestContext.initializeContext (); Future <Book> F1 = BookService.Test10 (1L); Future <Book> f2 = bodeService.test10 (2L); Future <Book> f3 = bodeService.test10 (3L); Buch B1 = f1.get (); Buch B2 = f2.get (); Buch B3 = f3.get (); Thread.sleep (3000); Future <Book> f4 = BookService.Test10 (4L); Buch B4 = f4.get (); System.out.println ("B1 >>>"+B1); System.out.println ("B2 >>>"+B2); System.out.println ("B3 >>>"+B3); System.out.println ("b4 >>>"+b4); context.close ();}Wie bei der vorherigen werden die ersten drei Anfragen zusammengeführt und die vierte Anfrage separat ausgeführt. OK, und das Ausführungsergebnis lautet wie folgt:
Zusammenfassen
Vorteile der Anfrage-Fusion haben Freunde gesehen, dass mehrere Anfragen in eine Anfrage zur einmaligen Verarbeitung verschmolzen werden, mit der die Netzwerkbandbreiten- und Thread-Pool-Ressourcen effektiv speichern können. Es gibt jedoch Vor- und Nachteile. Nach dem Einrichten der Anforderungsverschmelzung wurde möglicherweise eine Anfrage in 5 ms abgeschlossen. Jetzt müssen Sie jedoch auf weitere 10 ms warten, um zu sehen, ob zusammen andere Anfragen zusammen sind. Auf diese Weise wird der zeitliche Verbrauch einer Anfrage von 5 ms auf 15 ms erhöht. Wenn der von uns eingeleitete Befehl jedoch ein Befehl mit hohem Delay ist, können Sie zu diesem Zeitpunkt die Anforderungsverschiebung verwenden, da der Zeitfenster des Zeitfensters zu diesem Zeitpunkt unbedeutend ist. Darüber hinaus ist eine hohe Parallelität auch ein sehr wichtiges Szenario für Anforderungsfusionen.
Ok, das ist alles für unsere Anfrage zur Zusammenführung. Wenn Sie Fragen haben, hinterlassen Sie bitte eine Nachricht und diskutieren Sie. Ich hoffe, es wird für das Lernen aller hilfreich sein, und ich hoffe, jeder wird Wulin.com mehr unterstützen.