[Microservices] Basic implementation of RPC, gRPC and C/S architecture (Golang)

1. RPC

1.1 what & why need?

In a nutshell, RPC is the cornerstone of distributed systems .

RPC (Remote Procedure Call), the Chinese name is remote procedure call. It was first proposed by Xerox and defined as:
"RPC is a language-level communication protocol that allows a program running on a computer to call another address space using a certain channel as a communication medium ."

  1. In terms of type , RPC is a communication protocol;
  2. Functionally speaking , the function implemented by RPC is to call the address space of another machine on one machine, which may correspond to functions, variables, etc.;
  3. In terms of implementation means , RPC needs to use the transport layer in the computer network to realize pipeline communication. The pipeline communication at the transport layer can be understood as determining the two ends of the communication pipeline through IP addresses and port numbers.

With the development of the Internet, the "client-server-database" monolithic architecture (Monolithic Architecture) can no longer meet the increasingly complex business logic and increasing business access, so it is necessary to turn to the Microservices Architecture (Microservices Architecture). The following is the definition of microservices in Google Cloud Platform:

Microservice architecture (often shortened to microservices) refers to a form of architecture used to develop applications. Microservices allow a large application to be decomposed into independent components , each with its own area of ​​responsibility. When processing a user request, a microservice-based application may call many internal microservices to collectively generate its response.

According to the above definition, for a request in the microservice architecture, each service needs to call each other to finally generate a corresponding response, so the call between services becomes a key issue. And RPC can just solve this problem, so some people say "If you want to understand microservices, you must first get RPC" . Adding a suitable RPC framework to the microservice architecture can not only reduce the development cost of the microservice architecture, but also improve the call efficiency between services.

2. gRPC

2.1 A general open source framework

The Chinese version of gRPC official documentation: Open Source China . It seems that it has not been updated for a long time, please refer to docs for the latest English documents .

gRPC, originally developed by Google , is a language-neutral, platform-neutral, open source remote procedure call (RPC) system. gRPC is designed based on the HTTP/2 standard , bringing features such as bidirectional flow, flow control, header compression, and multiplexing requests on a single TCP connection. These features make it perform better on mobile devices , saving power and space. According to grpc.io , the framework currently supports multiple languages, including Java, C#, Go, C++, Dart, Python, Kotlin, PHP, Ruby, Objective-C, and Node.

2.2 Configure the gRPC environment

  • Configure the gRPC core library in go.mod (will be placed $GOPATH/pkgin )
$ go get google.golang.org/grpc
  • Download the code generation plugin for the corresponding language (will be placed $GOPATH/binin )
$ 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 realizes simple RPC service

3.1 Write proto file and generate corresponding Go code

Partial syntax of proto file

  1. serviceservice name { rpcrpc method name (request message) returns(response message) { } }
  2. messagemessage name { variable type variable name = position in the message; }

Write the server.proto file, the declaration syntax proto3is servicesimilar to that in Go func, messagesimilar to that in Go struct. rpcIndicates that ShakeHands is an RPC method that accepts requests ShakeReqand returns results 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;
}

Then enter the directory where the proto file is located and execute the protoc command.

$ cd path/to/proto/file
$ protoc --go_out=. server.proto
$ protoc --go-grpc_out=. server.proto

The generated files are as follows, –go_out indicates .pb.gothe directory location of the file output, and –go-grpc_out indicates _grpc.pb.gothe directory location of the file output.

3.2 Realize the server code

The main process is as follows:

  1. Implement _grpc.pb.gothe services (or RPC methods) defined in the file.
  2. Open the TCP port.
  3. Create a gRPC service and register the implemented service in the gRPC service.
  4. Start the gRPC service.
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 Client without security authentication

The logic of the client is very simple, which is to establish a connection with the server:

  1. Dial and initiate a connection. grpc.Dial()IP address and port of the server;
  2. _grpc.pb.goCreate a client instance through the method provided by the file;
  3. Call the RPC method to initiate the request.
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())
}

3.4 Perform SSL/TLS security authentication

Guess you like

Origin blog.csdn.net/weixin_45651194/article/details/129930250