1. CRP
1.1 ¿Qué y por qué necesita?
En pocas palabras, RPC es la piedra angular de los sistemas distribuidos .
RPC (llamada a procedimiento remoto), el nombre chino es llamada a procedimiento remoto. Fue propuesto por primera vez por Xerox y definido como:
"RPC es un protocolo de comunicación a nivel de idioma que permite que un programa que se ejecuta en una computadora llame a otro espacio de direcciones utilizando un canal determinado como medio de comunicación ".
- En términos de tipo , RPC es un protocolo de comunicación;
- Funcionalmente hablando , la función implementada por RPC es llamar al espacio de direcciones de otra máquina en una máquina, lo que puede corresponder a funciones, variables, etc.;
- En términos de medios de implementación , RPC necesita usar la capa de transporte en la red informática para realizar la comunicación de tubería. La comunicación de canalización en la capa de transporte puede entenderse como la determinación de los dos extremos de la canalización de comunicación a través de direcciones IP y números de puerto.
Con el desarrollo de Internet, la arquitectura monolítica "cliente-servidor-base de datos" (Arquitectura Monolítica) ya no puede cumplir con la lógica empresarial cada vez más compleja y el aumento del acceso empresarial, por lo que es necesario recurrir a la Arquitectura de Microservicios (Arquitectura de Microservicios). La siguiente es la definición de microservicios en Google Cloud Platform:
La arquitectura de microservicios (a menudo abreviada como microservicios) se refiere a una forma de arquitectura utilizada para desarrollar aplicaciones. Los microservicios permiten descomponer una gran aplicación en componentes independientes , cada uno con su propia área de responsabilidad. Al procesar una solicitud de usuario, una aplicación basada en microservicios puede llamar a muchos microservicios internos para generar colectivamente su respuesta.
De acuerdo con la definición anterior, para una solicitud en la arquitectura de microservicios, cada servicio debe llamarse entre sí para finalmente generar una respuesta correspondiente, por lo que la llamada entre servicios se convierte en un tema clave. Y RPC puede resolver este problema, por lo que algunas personas dicen "Si desea comprender los microservicios, primero debe obtener RPC" . Agregar un marco RPC adecuado a la arquitectura de microservicios no solo puede reducir el costo de desarrollo de la arquitectura de microservicios, sino también mejorar la eficiencia de las llamadas entre servicios.
2. gRPC
2.1 Un marco general de código abierto
La versión china de la documentación oficial de gRPC: Open Source China . Parece que no se ha actualizado durante mucho tiempo, consulte docs para obtener los últimos documentos en inglés .
gRPC, desarrollado originalmente por Google , es un sistema de llamada a procedimiento remoto (RPC) de código abierto , neutral en cuanto al idioma y la plataforma . gRPC está diseñado en base al estándar HTTP/2 y ofrece funciones como flujo bidireccional, control de flujo, compresión de encabezado y solicitudes de multiplexación en una sola conexión TCP. Estas características hacen que funcione mejor en dispositivos móviles , ahorrando energía y espacio. Según grpc.io , el marco actualmente admite varios lenguajes, incluidos Java, C#, Go, C++, Dart, Python, Kotlin, PHP, Ruby, Objective-C y Node.
2.2 Configurar el entorno gRPC
- Configure la biblioteca principal de gRPC en go.mod (se colocará
$GOPATH/pkg
en )
$ go get google.golang.org/grpc
- Descargue el complemento de generación de código para el idioma correspondiente (se colocará
$GOPATH/bin
en )
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
3. Golang realiza un servicio RPC simple
3.1 Escriba el archivo de prototipo y genere el código Go correspondiente
Sintaxis parcial del archivo proto
service
nombre del servicio {rpc
nombre del método rpc (mensaje de solicitud)returns
(mensaje de respuesta) { } }message
nombre del mensaje { tipo de variable nombre de la variable = posición en el mensaje; }
Escriba el archivo server.proto, la sintaxis de la declaración proto3
es service
similar a la de Go func
, message
similar a la de Go struct
. rpc
Indica que ShakeHands es un método RPC que acepta solicitudes ShakeReq
y devuelve resultados ShakeRes
.
syntax = "proto3";
option go_package = ".;service"; // 生成的.go文件在哪个目录的哪个包下(用;隔开 目录;包名)
service ShakeHands {
rpc ShakeHands(ShakeReq) returns (ShakeRes) {
}
}
message ShakeReq {
string requestName = 1; // 这是在定义变量在 message 中的位置
}
message ShakeRes {
string responseMsg = 1;
}
Luego ingrese al directorio donde se encuentra el archivo proto y ejecute el comando protoc.
$ cd path/to/proto/file
$ protoc --go_out=. server.proto
$ protoc --go-grpc_out=. server.proto
Los archivos generados son los siguientes: –go_out indica .pb.go
la ubicación del directorio de la salida del archivo y –go-grpc_out indica _grpc.pb.go
la ubicación del directorio de la salida del archivo.
3.2 Realizar el código del servidor
El proceso principal es el siguiente:
- Implemente
_grpc.pb.go
los servicios (o métodos RPC) definidos en el archivo. - Abra el puerto TCP.
- Cree un servicio gRPC y registre el servicio implementado en el servicio gRPC.
- Inicie el servicio gRPC.
package main
import (
"context"
"fmt"
"net"
"google.golang.org/grpc"
pb "gRPC/server/proto"
)
type server struct {
pb.UnimplementedShakeHandsServer
}
func (s *server) ShakeHands(ctx context.Context, req *pb.ShakeReq) (res *pb.ShakeRes, err error) {
return &pb.ShakeRes{
ResponseMsg: "res: hello!" + req.RequestName}, nil
}
func main() {
listen, _ := net.Listen("tcp", "127.0.0.1:9999") // 开启tcp端口
grpcServer := grpc.NewServer() // 创建grpc服务
pb.RegisterShakeHandsServer(grpcServer, &server{
}) // 在grpc服务中注册我们的服务
err := grpcServer.Serve(listen) // 启动服务
if err != nil {
fmt.Println("server error!")
return
}
}
3.3 Cliente sin autenticación de seguridad
La lógica del cliente es muy simple, que es establecer una conexión con el servidor:
- Marque e inicie una conexión.
grpc.Dial()
dirección IP y puerto del servidor; _grpc.pb.go
Cree una instancia de cliente a través del método proporcionado por el archivo;- Llame al método RPC para iniciar la solicitud.
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "gRPC/server/proto"
)
func main() {
conn, err := grpc.Dial("127.0.0.1:9999", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
fmt.Println("connection error!")
}
defer conn.Close()
client := pb.NewShakeHandsClient(conn) // 建立连接
resp, err := client.ShakeHands(context.Background(), &pb.ShakeReq{
RequestName: "test"})
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(resp.GetResponseMsg())
}