1. Introduction to gRPC
gRPC is a high-performance, open source and general remote procedure call (RPC) framework, open source and maintained by Google. It uses Protocol Buffers (protobuf) as the interface definition language (IDL) to provide cross-platform and cross-language RPC call support. gRPC has the following characteristics:
- High performance : Using the HTTP/2 protocol, supporting features such as multiplexing and flow control, it can efficiently transmit large amounts of data between the client and the server. At the same time, gRPC also uses platform-optimized serialization and deserialization technology to improve communication efficiency.
- Simple and easy to use : gRPC's IDL language is simple and easy to understand, and it also provides tools for automatically generating code to facilitate user development. Users only need to define the IDL and generate code to make remote procedure calls in the code in a manner similar to local function calls.
- Multi-language support : gRPC supports multiple programming languages, such as C++, Java, Python, Go, Ruby, etc., and can make RPC calls between different programming languages.
- Scalability : gRPC supports various extensions, including interceptors, load balancing, authentication and authorization, etc., to meet the needs of different scenarios.
- Security : gRPC supports SSL/TLS secure transmission, and also provides a token-based authentication mechanism to ensure communication security.
In short, gRPC provides an efficient, scalable, multi-language, and secure RPC framework suitable for inter-service communication in large-scale distributed systems, such as microservice architecture.
This article takes go as an example to introduce how to use gRPC to develop a simple service.
2. Preparation
2.1 Install protoc
From the precompiled version of protoc corresponding to the github/usr/local/
system, unzip it to the following. Taking v22.3 as an example, the specific operations are as follows:
wget https://github.com/protocolbuffers/protobuf/releases/download/v22.3/protoc-22.3-linux-x86_64.zip
unzip protoc-22.3-linux-x86_64.zip -d /usr/local/
ldconfig
protoc --version
# libprotoc 22.3
2.2 Install go related plug-ins
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
3. Practice
3.1 Write proto file
syntax = "proto3";
option go_package = "./;hello";
package hello;
message HelloRequest{
string name = 1;
}
message HelloResponse{
string message = 1;
}
service ExampleService{
rpc SayHi (HelloRequest) returns (HelloResponse);
}
service ExampleService
It is the service we defined, rpc SayHi (HelloRequest) returns (HelloResponse);
which is the interface provided in the service. protoc will generate the corresponding code based on the proto file we defined.
3.2 Use protoc to generate code
Execute the following command in the terminal to generate the code we need:
protoc --go_out=. --go-grpc_out=. hello.proto
--go_out specifies the generation directory of go files, --go-grpc_out specifies the generation directory of grpc files
At this time, when you open the generated go file, you will most likely find a red error. At this time, you can synchronize go mod tidy
the dependencies in the current directory.
3.3 Write server-side code
The example simply implements an echo service. The server code is as follows:
package main
import (
"context"
"net"
pb "github.com/mengbin92/hello/protos/hello"
"google.golang.org/grpc"
)
// 服务实体
type HelloService struct {
pb.UnimplementedExampleServiceServer
}
// 实现我们proto文件定义的接口
func (sv *HelloService) SayHi(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
return &pb.HelloResponse{Message: "hello " + in.Name}, nil
}
func main() {
// 创建grpc服务示例
sv := grpc.NewServer()
// 注册我们的服务
pb.RegisterExampleServiceServer(sv, new(HelloService))
// 绑定端口,提供服务
lis, err := net.Listen("tcp", ":50001")
if err != nil {
panic(err)
}
// 启动服务
sv.Serve(lis)
}
After starting the service, the server will block and wait for the client's connection until it receives kill
a signal:
go run server.go
3.4 Implement client
package main
import (
"context"
"fmt"
pb "github.com/mengbin92/hello/protos/hello"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
// 创建grpc连接
conn, err := grpc.Dial("localhost:50001", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
defer conn.Close()
// 实例化客户端
client := pb.NewExampleServiceClient(conn)
// 发送请求
req := &pb.HelloRequest{Name: "world"}
resp, err := client.SayHi(context.TODO(), req)
if err != nil {
panic(err)
}
fmt.Printf("get response from server: %s\n", resp.Message)
}
After the client starts, it sends it to the server world
, and the server returns hello world
:
go run client.go
# get response from server: hello world
At this point, a simple gRPC service has been completed.