Ich war neugierig, wie gRPC-Java funktioniert, also habe ich versucht, Code zu lesen

Einführung

Ich habe gRPC Java Tutorial ausprobiert und war neugierig, wie es funktioniert, also habe ich verschiedene Dinge untersucht.

--GRPC-Wie man Java benutzt, wird im Tutorial beschrieben, daher werde ich es nicht im Detail erklären. ――Es ist eine Zusammenfassung dessen, was ich über die Kommunikation verstanden habe und wie die detaillierte interne Implementierung aussieht.

Bestätigte Version

releases: gRPC-Java v1.16.1

compile 'io.grpc:grpc-netty-shaded:1.16.1'
compile 'io.grpc:grpc-protobuf:1.16.1'
compile 'io.grpc:grpc-stub:1.16.1'

Über gRPC

Zunächst werden zu gRPC die Punkte aus Official Document extrahiert.

type Überblick
A simple RPC Gibt 1 Antwort für 1 Anfrage zurück
A server-side streaming RPC Gibt mehrere Antworten für eine Anfrage zurück
A client-side streaming RPC Gibt eine Antwort für mehrere Anforderungen zurück
A bidirectional streaming RPC Tauschen Sie mehrere Anfragen und mehrere Antworten in beide Richtungen aus

Über gRPC-Java

gRPC-Punkte der Java-Implementierung.

Über Netty

Netty, das in gRPC-Java verwendet wird, ist ein Framework, mit dem Sie nicht blockierende E / A-Anwendungen (NIO) in Java erstellen können. (Verwenden Sie kein Java-Servlet.)

Der in gRPC angezeigte Thread, der Ereignisname von NIO und die Verarbeitung von Netty sind wie folgt.

Charakter Rolle
Boss-Thread
(ServerBootstrap parentGroup)
Ich von dem Netzwerk von Netty verwendet/Ein Thread, der O erkennt. Eine wird standardmäßig beim Start generiert.
Arbeitsthread
(ServerBootstrap childGroup)
Ich habe von Netty benutzt/O Ein Thread, der jedes Ereignis verarbeitet. Der Standardwert istAnzahl der Prozessoren x 2
Executor-Thread Ein Thread, der die in gRPC definierten Methoden ausführt. Wird für jeden Methodenaufruf generiert.
I/O Ereignisname Überblick
OP_ACCEPT Verbindung vom Client
OP_READ Netzwerk I./Lesen Sie O.
OP_WRITE Netzwerk I./Exportieren Sie O.

Ergänzung

Für Netty ist "JJUG CCC 2018 Spring - I-7 (I) First Netty" sehr hilfreich. Wurde.

Über HTTP / 2

Aus Googles Einführung in HTTP / 2 werden die Punkte zum Verständnis von gRPC entnommen.

In HTTP / 1.x wird durch Zeilenumbrüche getrennter Klartext als eine Anforderung (oder Antwort) betrachtet, in HTTP / 2 wird dies jedoch als eine Nachricht ausgedrückt und die Nachricht wird weiter in die folgenden Rahmeneinheiten unterteilt.

--HEADERS-Frame (HTTP / 1.x-Header) --DATA-Frame (HTTP / 1.x-Body)

Darüber hinaus können Frames mit einer einzigen TCP-Verbindung parallel und in beide Richtungen ausgetauscht werden. Mit anderen Worten, es ist nicht erforderlich, für jede Anforderung eine TCP-Verbindung herzustellen, und für eine Anforderung können mehrere Antworten und Server-Pushs durchgeführt werden.

Übersicht über die gRPC-Java-Verarbeitung

Von diesem Punkt an wird es so etwas wie "welcher Teil des Codes und welcher Prozess ~" sein, also werde ich vorher zusammenfassen, was ich über die Reihe von Prozessen interpretiert habe.

  1. Der gRPC-Server erzeugt einen Boss-Thread, der von Netty beim Start verwendet wird
  2. Der gRPC-Client sendet eine Anfrage an den gRPC-Server
  3. Wenn der Boss-Thread das "OP_ACCEPT" des Netzwerk-E / A-Ereignisses erkennt, erstellt er einen Netty-Worker-Thread (oder ruft ihn aus dem Pool ab) und delegiert die Verarbeitung von "OP_READ" / "OP_WRITE".
  4. Der Worker-Thread wird jedes Mal aufgerufen, wenn ein E / A-Ereignis wie der Aufbau einer TCP-Verbindung (3-Wege-Handshake usw.), ein HTTP / 2-HEADERS-Frame, ein DATA-Frame usw. auftritt.
  5. Nach dem Empfang der für den gRPC-Aufruf erforderlichen HTTP / 2-Nachricht (mehrere Frames) vom Client erzeugt der Worker-Thread einen ausführbaren Thread zum Ausführen der gRPC-Methode.
  6. Netty ist ein Ereignisschleifenmechanismus, der nur für den Boss-Thread und den Worker-Thread ausgeführt wird. Von dort wird jedoch für jeden gRPC-Methodenaufruf ein Thread erstellt.
  7. Daher scheinen Netty-Threads nicht blockiert zu sein, selbst wenn die Blockierungsverarbeitung in der gRPC-Methode ausgeführt wird.
  8. Der Executor-Thread führt die gRPC-Methode aus und registriert die Antwort "OP_WRITE"
  9. Der Worker-Thread erkennt "OP_WRITE" und gibt eine Antwort an den Client zurück.
  10. Wenn der Client weiterhin eine Verbindung herstellt, muss keine TCP-Verbindung wiederhergestellt werden, sodass die Prozesse "5. ~ 7." viele Male parallel ausgeführt werden können.
  11. Trennen Sie TCP, wenn der Client die Verbindung trennt

Code lesen auf der Serverseite

TODO Ich schreibe es für mein eigenes Memo, also werde ich es später hinzufügen und organisieren. (Es war schwierig zu verfolgen, wie verschiedene Threads erstellt und neue Threads mit Rückrufen erstellt wurden. Ich würde mich freuen, wenn Sie mir mitteilen könnten, ob ich einen Fehler gemacht habe.)

Anlaufen

Anfrage erhalten

getFeature:130, RouteGuideServer$RouteGuideService (grpc.routeguide)
invoke:462, RouteGuideGrpc$MethodHandlers (grpc.routeguide)
onHalfClose:171, ServerCalls$UnaryServerCallHandler$UnaryServerCallListener (io.grpc.stub)
halfClosed:283, ServerCallImpl$ServerStreamListenerImpl (io.grpc.internal)
runInContext:710, ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed (io.grpc.internal)
run:37, ContextRunnable (io.grpc.internal)
run:123, SerializingExecutor (io.grpc.internal)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)

Recommended Posts

Ich war neugierig, wie gRPC-Java funktioniert, also habe ich versucht, Code zu lesen
Java9 war enthalten, also habe ich jshell ausprobiert.
Ich war neugierig, wie man Optional orElse () und orElseGet () richtig verwendet.
Ich war neugierig auf all_month und las ActiveSupport DateAndTime :: Calculations
Ich habe versucht, den Quellcode zu analysieren
Über die Sache, dass ich süchtig danach war, wie man Hashmap benutzt