** * Cet article a été créé le 7 novembre 2019 Essayons gRPC avec Go et Docker --LiBz Tech Blog Même contenu **
salut! Je suis Watanabe, un ingénieur. Cela fait un an que j'ai rejoint LiB en novembre. Ceci est mon 4ème article sur ce blog.
Dans la précédente "Histoire de l'introduction d'un framework sans serveur très semblable à Rails" Ruby on Jets "dans un environnement de production" , Développeur Jets ** tongueroo ** et créateur Ruby ** Matsumoto Yukihiro C'était très encourageant de le partager avec de nombreuses personnes, dont **! Merci tout le monde.
Cette fois, j'écrirai sur le framework RPC ** gRPC ** développé par Google.
Il s'agit d'une version open source du framework RPC (Remote Procedure Call) appelé stubby utilisé dans Google.
Grâce aux fonctionnalités ci-dessus, ** gRPC peut résoudre les problèmes de connexion et de transfert de données entre les systèmes micro-desservis, et peut communiquer efficacement **.
L'interface doit être unifiée entre plusieurs systèmes
Les systèmes changent fréquemment, ce qui rend difficile d'assurer la cohérence de tous les systèmes
** -> Le code source du serveur / client peut être généré automatiquement à partir de ProtocolBuffer (fichier .proto), et plusieurs langues peuvent être sélectionnées **
--Documents pour comprendre les spécifications de plusieurs systèmes (spécifications, wiki, Swagger, etc.) Omissions de mise à jour, erreurs de description
** -> La communication entre les services est générée à partir du fichier proto, donc le fichier proto a les spécifications correctes (le code source est généré sur la base du fichier proto, donc aucune omission ou erreur ne se produit) **
** -> HTTP / 2 peut gérer plusieurs requêtes et réponses avec une seule connexion TCP **
** -> Grâce à la communication HTTP / 2, la connexion peut être utilisée en continu sans être supprimée **
Bien sûr, il n'y a pas seulement des avantages mais aussi des inconvénients. Le fait que la norme de communication soit HTTP / 2 signifie que ** les navigateurs et les équilibreurs de charge qui ne le prennent pas en charge ne peuvent pas recevoir de requêtes **.
Pour les navigateurs, un proxy inverse tel que grpc-gateway et grpc-web Il n'y a aucun problème si vous utilisez une bibliothèque qui La communication entre les services est le protocole HTTP2, et seule la communication entre le navigateur et le serveur est le protocole HTTP1, de sorte que certaines personnes peuvent se sentir mal à l'aise avec le mixage.
La vérification du fonctionnement du serveur gRPC est également un peu gênante. Vous pouvez vérifier le fonctionnement comme l'API conventionnelle avec curl, mais vous ne pouvez pas utiliser curl avec gRPC. (Récemment, vous pouvez vérifier le fonctionnement de gRPC comme curl gRPCurl et gRPC UI qui est un client GUI pour gRPC. hinastory / items / 131cb603af34e3235ccf) Il semble y avoir un outil)
Let's try gRPC
Introduction à gRPC commençant par Go Essayez gRPC avec Golang
Installez les trois ci-dessus.
gRPC
$ go get -u google.golang.org/grpc
protoc
Cela dépend du système d'exploitation. Veuillez installer depuis ici.
protoc-gen-go
$ go get -u github.com/golang/protobuf/protoc-gen-go
Dockerfile
Puisque nous utiliserons Docker cette fois, nous préparerons également un Dockerfile et docker-compose.yml.
FROM golang:1.13.1
RUN apt-get update && apt-get install -y unzip
# Install protobuf
# @see https://github.com/yoshi42662/go-grpc/blob/master/server/Dockerfile
RUN mkdir -p /tmp/protoc && \
curl -L https://github.com/protocolbuffers/protobuf/releases/download/v3.10.0/protoc-3.10.0-linux-x86_64.zip > /tmp/protoc/protoc.zip && \
cd /tmp/protoc && \
unzip protoc.zip && \
cp /tmp/protoc/bin/protoc /usr/local/bin && \
chmod go+rx /usr/local/bin/protoc && \
cd /tmp && \
rm -r /tmp/protoc
WORKDIR /study-grpc
COPY . /study-grpc
RUN go get -u google.golang.org/grpc
RUN go get -u github.com/golang/protobuf/protoc-gen-go
docker-compose.yml
Pour le moment, il est bon que le conteneur soit en cours d'exécution, donc je le règle sur command: bash
docker-compose.yml
version: '3.7'
services:
study-grpc:
build: .
container_name: "study-grpc"
ports:
- 1234:1234
volumes:
- .:/study-grpc
command: bash
tty: true
Définissez l'interface dans le fichier proto et générez le code.
J'ai créé pb / cat.proto
.
syntax = "proto3";
service Cat {
rpc GetMyCat (GetMyCatMessage) returns (MyCatResponse) {}
}
message GetMyCatMessage {
string target_cat = 1;
}
message MyCatResponse {
string name = 1;
string kind = 2;
}
Notez que si vous oubliez d'écrire syntax =" proto3 "
, il sera interprété comme proto2.
gRPC utilise généralement proto3. La différence entre proto2 et proto3 est ici L'article était facile à comprendre.
La partie numérique de string name = 1
est le numéro de tag. Le numéro de tag est utilisé pour distinguer les champs. On dit qu'une fois le numéro attribué, il vaut mieux ne pas le changer, donc s'il y a un changement, un nouveau numéro sera attribué.
Ensuite, allez dans le conteneur et compilez le fichier proto pour générer le code source.
#Démarrage du conteneur
$ docker-compose up
#Entrez dans le conteneur
$ docker exec -it study-grpc bash
#exécution de la commande protocol
$ protoc --go_out=plugins=grpc:. ./pb/cat.proto
C'est OK si pb / cat.pb.go
est généré.
Créez server.go
.
package main
import (
"context"
"errors"
"google.golang.org/grpc"
"log"
"net"
cat "study-grpc/pb"
)
type myCatService struct{}
func (s *myCatService) GetMyCat(ctx context.Context, message *cat.GetMyCatMessage) (*cat.MyCatResponse, error) {
switch message.TargetCat {
case "tama":
return &cat.MyCatResponse{
Name: "tama",
Kind: "Maine Coon",
}, nil
case "mike":
return &cat.MyCatResponse{
Name: "mike",
Kind: "Norwegian Forest Cat",
}, nil
default:
return nil, errors.New("Not Found YourCat..")
}
}
func main() {
port, err := net.Listen("tcp", ":1234")
if err != nil {
log.Println(err.Error())
return
}
s := grpc.NewServer()
cat.RegisterCatServer(s, &myCatService{})
s.Serve(port)
}
Créez client.go
.
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"log"
cat "study-grpc/pb"
)
func main() {
conn, err := grpc.Dial("localhost:1234", grpc.WithInsecure())
if err != nil {
log.Fatal("connection error:", err)
}
defer conn.Close()
client := cat.NewCatClient(conn)
message := &cat.GetMyCatMessage{TargetCat: "mike"}
res, err := client.GetMyCat(context.Background(), message)
if err != nil {
log.Fatal(err)
}
fmt.Printf("result:%s\n", res)
}
Construisons et exécutons le "server.go" et le "client.go" créés.
#Entrez dans le conteneur
$ docker exec -it study-grpc bash
# server.construire aller&Courir
$ go build server.go
$ ./server
# client.construire aller&Courir
$ go build client.go
$ ./client
#S'il est difficile de construire, allez courir est ok
$ go run server.go
$ go run client.go
Résultat d'exécution
result:name:"mike" kind:"Norwegian Forest Cat"
Qu'as-tu pensé?
Le simple fait d'entendre le nom me fait penser «gRPC? ProtocolBuffer? Cela semble difficile», mais je pense que c'était plus facile que ce que j'avais imaginé quand j'ai bougé mes mains.
Il a déjà été adopté non seulement par Google, mais également par un certain nombre de grandes entreprises, et le nombre de cas dans les entreprises japonaises augmente régulièrement.
Les microservices présentent de nombreux défis, mais gRPC, qui résout la partie communication, est l'une des options, et je veux vraiment m'en souvenir.
Le code utilisé cette fois est résumé dans ce référentiel.
Recommended Posts