[JAVA] Ich dachte, dass die erste Zeichnung schneller sein würde, wenn ich Spring WebFlux verwenden würde, um 1 Million Daten vom Server abzurufen und im Browser anzuzeigen, also habe ich es versucht.

Neulich schrieb ich einen Artikel "Abrufen von Spring Web Flux Flux-Ergebnissen von JS mit Fetch API", aber mit dieser Methode Wenn Sie beispielsweise eine große Datenmenge im Browser anzeigen möchten und der Server nur die ersten zehn Elemente verarbeiten kann, zeigen Sie zuerst nur die ersten zehn Elemente im Browser an und fügen Sie dann die verarbeiteten Daten im Hintergrund hinzu. Gehen. Ich dachte, es wäre möglich, so etwas wie ** leicht ** zu machen, also habe ich es versucht.

Wenn der Benutzer eine große Datenmenge anfordert, besteht die Möglichkeit, diese durch Paging zu implementieren. Möglicherweise gibt es eine solche Option. Es ist ein Artikel über. Wir empfehlen diese Methode nicht.

Der hier versuchte wurde auf [GitHub] hochgeladen (https://github.com/ota-meshi/spring-webflux-x-cheetah-grid-example).

Inhalte verarbeiten

Fordern Sie eine Million Daten vom Server an und zeigen Sie die Ergebnisse im Browser-Raster an.

Technische Elemente verwendet

--Serverseite

Vergleich und Video

Ich werde Ihnen zuerst das Vergleichsergebnis zeigen.

Asynchrone Anforderung mit Spring WebFlux

Die Zeit bis zur ersten Zeichnung betrug 2.056 ms. Ich dachte, es wäre etwas früher, aber es scheint, dass es einige Zeit dauert, bis die erste nach der Ausgabe der SQL-Abfrage in der H2-Datenbank zurückgegeben wird. (Nun, ich glaube nicht, dass H2 für die Produktion bestimmt ist, daher kann nicht geholfen werden.) Das Video wurde geschnitten, aber danach dauert es ungefähr 40 Sekunden, um die Chorochoro-Daten zu erfassen und 1 Million auf der Clientseite zu speichern.

WebFlux.gif

Gewöhnliche Synchronisierungsanforderung

Die Zeit zum Zeichnen betrug 5.827 ms. Da ich sie alle auf einmal mitbringe, sind es die gleichen 5.827 ms in Bezug auf die Zeit, die benötigt wird, um 1 Million Artikel auf der Client-Seite zu speichern. Ich dachte, es wäre langsamer, aber ich habe nichts unternommen, um jeden Datensatz zu erstellen, und es gab nicht viele Informationen zu einem Datensatz. War es also überraschend schnell?

sync.gif

Implementierung

Ich werde auch über die Implementierung unten schreiben.

Controller (Serverseite)

Die Implementierung ist wie folgt.

	@Autowired
	private SqlConfig uroboroSQLConfig;

	@Autowired
	@Qualifier("jdbcScheduler")
	private Scheduler jdbcScheduler;

	@GetMapping
	public Flux<Person> all() {
		return Flux.<Person> create(sink -> {
			try (var agent = uroboroSQLConfig.agent()) {
				//Wählen Sie die Tabelle aus und generieren Sie einen Stream, der der Person-Klasse zugeordnet ist
				agent.queryWith("SELECT * FROM PERSON ORDER BY ID")
						.stream(Person.class)
						//Beenden, wenn abgebrochen
						.dropWhile(p -> sink.isCancelled())
						//Entität an FluxSink übergeben
						.forEach(sink::next);

				if (!sink.isCancelled()) {
					//Benachrichtigen Sie das Ende
					sink.complete();
				}
			}
		}).subscribeOn(jdbcScheduler);
	}

Die auf GitHub veröffentlichte Quelle ist hier /webflux/controller/PersonController.java#L27).

Für den DB-Zugriff von uroboroSQL ist "uroboroSQLConfig" erforderlich. Es hat nichts mit dem Hauptthema zu tun, also mach dir keine Sorgen, denke nur, es ist etwas für den DB-Zugriff und lies es in der Luft.

Der jdbcScheduler ist eineScheduler-Instanz von Reactor, die für die Parallelisierung erforderlich ist.

Definieren Sie "Scheduler" mit der entsprechenden Anzahl von Threads.

		}).subscribeOn(jdbcScheduler);

Durch das Übergeben werden die Verarbeitung des DB-Zugriffs und die Verarbeitung der Rückgabe einer Anforderung parallelisiert.

Der Rest ist Stornierungsabwicklung, Grundsätzlich einfach SELECT aus der DB und das Ergebnis mit sink.next (...) übergeben.

Anfrage (clientseitig)

[Fetch API](https: //developer.mozilla) mit der in Abrufen von Flux-Ergebnissen von Spring Web Flux von JS mit Fetch API beschriebenen Methode Stellen Sie eine Anfrage an den Server mit .org / ja / docs / Web / API / Fetch_API.

Anzeige im Raster (Client-Seite)

Die Implementierung ist wie folgt.

      const records = [];
      const grid = /*Cheetah Grid Instanz*/;
      let buffer = [];
      //...
      streamJsonForVue(this, "/api/persons", {}, rec => {
        buffer.push(rec);
        if (
          buffer.length >= 10000 ||
          (records.length < 10000 && buffer.length >= 1000) ||
          (records.length < 1000 && buffer.length >= 100)
        ) {
          records.push(...buffer);
          grid.records = records;
          buffer = [];
          //...
        }
      }).then(() => {
        records.push(...buffer);
        grid.records = records;
        //...
      });

Die auf GitHub veröffentlichte Quelle ist hier ) ist.

Die Variable "grid" enthält eine Instanz von Cheetah Grid. Wenn Sie der Eigenschaft "records" ein Array zuweisen, werden die angegebenen Daten auf dem Bildschirm angezeigt. Es zeigt.

Die Funktion "streamJsonForVue" wurde in "Abrufen von Flux-Ergebnissen von Spring Web Flux von JS mit der Fetch-API", [Fetch API] geschrieben. (https://developer.mozilla.org/ja/docs/Web/API/Fetch_API) wird verarbeitet. Außerdem unterbreche ich Fetch, wenn der Bildschirm verworfen wird, aber ich werde die Erklärung weglassen, da sie nichts mit dem Hauptthema zu tun hat.

Die vom Rückruf "streamJsonForVue" zurückgegebene Variable "rec" sind die Ein-Datensatz-Daten, die von "sink.next (...)" im Controller übergeben werden. Wenn Sie es nacheinander an "Grid" übergeben, wird das Neuzeichnen ausgeführt, und es ist für den Benutzer schwierig, den Bildschirm zu bedienen. Speichern Sie ihn daher im "Buffer" -Array. Wenn er sich bis zu einem gewissen Grad ansammelt (erste 100 Fälle), spiegeln Sie ihn im Raster wider Ich mache es.

Implementierung der Synchronisationsanforderung

Die auf GitHub veröffentlichte Quelle ist hier /webflux/controller/PersonController.java#L48) und [hier](https://github.com/ota-meshi/spring-webflux-x-cheetah-grid-example/blob/master/src/components/SampleCheetahGrid .vue # L131). Ich habe es nur zum Vergleich gemacht, aber es hat nichts mit dem Hauptthema zu tun, deshalb werde ich die Erklärung weglassen.

Impressionen umgesetzt

Was ich über die Implementierung dachte, war, dass es ** sehr einfach zu implementieren ** war. Meines Wissens war es schwierig, eine HTTP-Antwort asynchron an Stream zu senden, aber ich war überrascht, dass die Verwendung mit Spring WebFlux sehr einfach war.

Ergebnis

Wie ich bereits geschrieben habe, war in diesem Beispiel die für das erste Zeichnen erforderliche Zeit wie folgt.

Es war schade, dass dieses Beispiel nicht so effektiv war, wie ich erwartet hatte, aber wenn Sie die anfängliche Zeichnung wirklich beschleunigen möchten, können Sie es möglicherweise verwenden (?)

Recommended Posts

Ich dachte, dass die erste Zeichnung schneller sein würde, wenn ich Spring WebFlux verwenden würde, um 1 Million Daten vom Server abzurufen und im Browser anzuzeigen, also habe ich es versucht.
Ich habe versucht zu überprüfen, ob es Spaß machen würde, "Programmierung" und "Hobbys" zu kombinieren.
Ich habe versucht, YouTube-Video von DB mit haml aufzurufen und es eingebettet anzuzeigen
Ich habe versucht, mit Spring Data JPA zu beginnen