J'ai essayé le Tutoriel Java gRPC et j'étais curieux de savoir comment cela fonctionne, alors j'ai étudié diverses choses.
--GRPC-Comment utiliser Java est décrit dans le tutoriel, donc je ne vais pas l'expliquer en détail. ――C'est un résumé de ce que j'ai compris sur la façon de communiquer et sur la mise en œuvre interne détaillée.
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'
Tout d'abord, à propos de gRPC, les points sont extraits du Document officiel.
-Utilisez Protocol Buffers pour sérialiser les données à envoyer et recevoir et définir l'interface de RPC.
type | Aperçu |
---|---|
A simple RPC | Renvoie 1 réponse pour 1 requête |
A server-side streaming RPC | Renvoie plusieurs réponses pour une demande |
A client-side streaming RPC | Renvoie une réponse pour plusieurs demandes |
A bidirectional streaming RPC | Échangez plusieurs demandes et plusieurs réponses dans les deux sens |
gRPC-Points d'implémentation Java.
Du côté serveur, la partie contrôle de communication utilise Netty.
Cette fois, le traitement côté client n'a pas été beaucoup étudié.
Que ce soit Android ou non, c'est dans ServiceProviders # loadAll Détermination à l'aide de ClassLoader
faites.
Pour les non-Android, ServiceProviders # getCandidatesViaServiceLoader Utilisez java.util.ServiceLoader # load dans META-INF / services / io.grpc.ServerProvider Je reçois le cours écrit
J'ai découvert pour la première fois java.util.ServiceLoader # load. ..
Netty utilisé dans gRPC-Java est un framework qui vous permet de créer des applications d'E / S non bloquantes (NIO) en Java. (N'utilisez pas de servlet Java)
Le thread qui apparaît dans gRPC, le nom de l'événement de NIO et le traitement de Netty sont comme ceci.
--Détecte ʻOP_ACCEPT dans le thread de boss et enregistre l'événement ʻOP_READ
et ʻOP_WRITE
Personnage | rôle |
---|---|
fil de patron (ServerBootstrap parentGroup) |
I du réseau utilisé par Netty/Un thread qui détecte O. L'un est généré par défaut au démarrage. |
fil de travail (ServerBootstrap childGroup) |
J'ai utilisé par Netty/O Un thread qui traite chaque événement. La valeur par défaut estNombre de processeurs x 2。 |
thread exécuteur | Un thread qui exécute les méthodes définies dans gRPC. Généré pour chaque appel de méthode. |
I/O nom de l'événement | Aperçu |
---|---|
OP_ACCEPT | Connexion du client |
OP_READ | Réseau I/Lire O |
OP_WRITE | Réseau I/Exporter O |
Pour Netty, "JJUG CCC 2018 Spring --I-7 (I) First Netty" est très utile. Devenu.
De Google Introduction à HTTP / 2, les points pour comprendre gRPC sont extraits.
Dans HTTP / 1.x, le texte brut séparé par des sauts de ligne est considéré comme une demande (ou réponse), mais dans HTTP / 2, cela est exprimé comme un message, et le message est divisé en unités de trame suivantes.
De plus, les trames peuvent être échangées en parallèle et dans les deux sens avec une seule connexion TCP. En d'autres termes, il n'est pas nécessaire d'établir une connexion TCP pour chaque demande, et plusieurs réponses et poussées de serveur peuvent être effectuées pour une demande.
À partir de là, ce sera quelque chose comme "quelle partie du code et quel processus ~", donc avant cela, je vais résumer ce que j'ai interprété à propos de la série de processus.
, il crée un thread de travail Netty (ou le récupère du pool) et délègue le traitement de ʻOP_READ
/ ʻOP_WRITE`.TODO Je l'écris pour mon propre mémo, je vais donc l'ajouter plus tard et l'organiser. (Il était difficile de suivre la création de divers threads et de créer de nouveaux threads avec des rappels, donc je serais heureux si vous pouviez me dire si j'ai fait une erreur.)
--Exécuter RouteGuideServer # main --Obtenir une instance de ServerBuilder avec ServerBuilder # forPort --Dans ServiceProviders # loadAll, regardez ClassLoader pour déterminer s'il s'agit d'une application Android ou non.
dans io.netty.channel.nio.NioEventLoop.run --Passez ThreadPoolExecutor avec ThreadFactory (ThreadFactoryBuilder $ ThreadFactory) pour créer un thread avec le nom
grpc-default-executor-% d` à l'exécuteur--Lorsque le thread de travail accepte la demande d'appel de méthode gRPC, NettyServerHandler est ServerImpl $ ServerTransportListenerImpl # streamCreated /io/grpc/netty/NettyServerHandler.java#L437)
--ServerImpl $ ServerTransportListenerImpl # streamCreated [Passer une instance de StreamCreated qui hérite de ContextRunnable à SerializingExecutor qui encapsule ThreadPoolExecutor](https://github.com/grpc/grpc-java/blob/v1.16.1/core/src/ main / java / io / grpc / internal / ServerImpl.java # L495)
--Cette exécution exécute la tâche exécutable suivante avec le nom de thread grpc-default-executor-% d
dans ThreadFactoryBuilder $ ThreadFactory.
--StreamCreated # run-> StreamCreated # runInContext est exécuté
--And ServerImpl # JumpToApplicationThreadServerStreamListener $ MessagesAvailable # runInContext est appelé
getFeature
définie dans gRPC est appelée, elle ressemble à cecigetFeature: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