SoFunction
Updated on 2025-03-05

The use of golang microservices gRPC and Protobuf

What is RPC?

The so-called RPC (remote procedure call remote procedure call) framework actually provides a set of mechanisms that enable communication between applications and also comply with the server/client model. When using it, the client calls the interface provided by the server side just like calling a local function.

What is gRPC?

Like many RPC systems, gRPC is based on the idea of ​​defining a service, specifying methods that can be called remotely using its parameters and return types. By default, gRPC uses protocol buffers as interface definition language (IDL) to describe the structure of service interfaces and payload messages.

What are the benefits of gRPC and what scenarios do you need to use gRPC in

Since it is a server/client model, can we just use the restful API to satisfy it? Why do we still need RPC? Let's take a look at what advantages RPC has

gRPC vs. Restful API

Both gRPC and restful APIs provide a set of communication mechanisms for server/client model communication, and they both use http as the underlying transmission protocol (strictly speaking, gRPC uses http2.0, while restful API is not necessarily). However, gRPC still has some unique advantages, as follows:

  • gRPC can define interfaces through protobuf, so that there can be more stringent interface constraints. For protobuf, please refer to the author's previous articleGoogle Protobuf simple tutorial
  • In addition, the data can be serialized into binary encoding through protobuf, which will greatly reduce the amount of data to be transmitted, thereby greatly improving performance.
  • gRPC can easily support streaming communication (theoretically, streaming mode can be used through http2.0, but the restful API of web services usually seems to be rarely used like this. Usually streaming data applications such as video streaming generally use special protocols such as HLS, RTMP, etc. These are not our usual web services, but have special server applications.)

Use scenarios

  • When strict constraints are needed on the interface, for example, we provide a public service, and many people, even outside the company, can access this service. At this time, we hope to have stricter constraints on the interface, and we do not want the client to pass arbitrary data to us. Especially considering security factors, we usually need to impose stricter constraints on the interface. At this time, gRPC can provide strict interface constraints through protobuf.
  • When there are higher performance requirements. Sometimes our service needs to pass a large amount of data, but it hopes that it will not affect our performance. You can also consider gRPC service at this time, because through protobuf, we can convert data compression encoding into binary format, usually the amount of data passed is much smaller, and through http2, we can implement asynchronous requests, which greatly improves communication efficiency.

However, usually we do not use gRPC alone, but use gRPC as a component. This is because in production environment, when we face large concurrency, we need to use a distributed system to deal with it, and gRPC does not provide some necessary components related to distributed systems. Moreover, true online services also need to provide necessary components including load balancing, current limiting fuse, monitoring and alarm, service registration and discovery, etc. However, this is not the topic discussed in this article. Let’s continue to see how to use gRPC first.

The use of gRPC usually includes the following steps

  • Define interface and data types through protobuf
  • Writing gRPC server code
  • Writing gRPC client code

Installation of protobuf

mac:brew install protobuf

windows: protoc download:Official address, then add the bin path to the path environment variable

linux:

Install the required dependency package:

[root@localhost ~]# yum -y install autoconf automake libtool curl make g++ unzip 
[root@localhost ~]# unzip  
[root@localhost ~]# cd protobuf-master 

The script file that generates the configure file. If this step is not performed, the following operations will not be possible.

[root@localhost protobuf-master]# ./ 
[root@localhost protobuf-master]# ./configure 

You can modify the installation directory through the ./configure --prefix= command, and install it in /usr/local/protobuf.

[root@localhost protobuf-master]# ./configure --prefix=/usr/local/protobuf 
[root@localhost protobuf-master]# make
[root@localhost protobuf-master]# make check
[root@localhost protobuf-master]# make install 
[root@localhost protobuf-master]# ldconfig # refresh shared library cache. 

Installation successfully

[root@localhost protobuf-master]# protoc -I=./ --cpp_out=./ 

Install the grpc package

go get -u /golang/protobuf/{proto,protoc-gen-go}
go get -u /grpc
protoc --go_out=plugins=grpc:. *.proto

Define interfaces and data types

syntax = "proto3";

package rpc_package;

// define a service
service HelloWorldService {
 // define the interface and data type
 rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// define the data type of request
message HelloRequest {
 string name = 1;
}

// define the data type of response
message HelloReply {
 string message = 1;
}

Use the protobuf generation tool to generate library functions in the corresponding language

protoc --go_out=plugins=grpc:. 


// 
 
import (
 "log"
 "net"
 
 "/x/net/context"
 "/grpc"
 pb "helloworld/helloworld"
)
 
const (
 port = ":50051"
)
 
type server struct {}
 
func (s *server) SayHello(ctx , in *) (*, error) {
 return &{Message: "Hello " + }, nil
}
 
func main() {
 lis, err := ("tcp", port)
 if err != nil {
  ("failed to listen: %v", err)
 }
 s := ()
 (s, &server{})
 (lis)
}

package main
 
//
 
import (
 "log"
 "os"
 
 "/x/net/context"
 "/grpc"
 pb "helloworld/helloworld"
)
 
const (
 address  = "localhost:50051"
 defaultName = "world"
)
 
func main() {
 conn, err := (address, ())
 if err != nil {
  ("did not connect: %v", err)
 }
 defer ()
 c := (conn)
 
 name := defaultName
 if len() >1 {
  name = [1]
 }
 r, err := ((), &{Name: name})
 if err != nil {
  ("could not greet: %v", err)
 }
 ("Greeting: %s", )
}

The above is the detailed content of the use of gRPC and Protobuf in golang microservices. For more information about golang gRPC and Protobuf, please follow my other related articles!