First of all, we have a preliminary understanding of Go-Micro from the example of HelloWorld that we are most familiar with

The source address

  • The source address
  • Comprehensive micro service project of Airentals

ProtoBuf

Introduction to the

Protocol Buffers (ProtoBuf) is a language-independent, platform-independent, extensible method of serializing structured data. It can be used for communication protocols, data storage, etc.

Protocol Buffers is a flexible, efficient, and automated method for serializing structured data – similar to XML, but smaller (3 to 10 times), faster (20 to 100 times), and simpler than XML.

Json XML is based on text format, protobuf is binary format.

You can use ProtoBuf to define data structures and then use the ProtoBuf tool to generate data structure libraries in various language versions for manipulating ProtoBuf data

This tutorial covers the syntax of the latest version of protobuf Proto3.

Example of using ProtoBuf

Create a.proto file to define the data structure

With a ProtoBuf, you first need to define data structures (messages) using the ProtoBuf syntax, and these defined data structures are stored in files with a. Proto suffix.

Example:

File name: Response.proto

// Specify the version of the protobuf. Proto3 is the latest syntax version. Struct message Response {string data = 1; struct message Response {string data = 1; Int32 status = 2; int32 status = 2; Int status = int32; int status = status;Copy the code

Proto file, the serial number behind the field, can not be repeated, defined can not be modified, can be understood as the unique ID of the field.

Install the ProtoBuf compiler

Github address for protobuf: github.com/protocolbuf…

The compiler for protobuf is called Protoc, find the latest version of the installation package in the url above, download and install.

Protoc-3.9.1-win64. zip, Windows 64-bit version of the compiler, download, unzip to your desired installation directory.

Tip: After installation, add the [protoc installation directory]/bin PATH to the PATH environment variable

Open CMD, command window to execute protoc command, no error, it has been installed successfully.

More protoc tutorials can be found here

grpc

GRPC is a high-performance, cross-platform, open source, and generic RPC framework for mobile and HTTP/2 design. Currently available in C/C++, Java, Python, Ruby, C#, PHP, Node.js, Go, and almost any language you can think of.

GRPC is designed based on the HTTP/2 standard and brings features such as bidirectional streaming, flow control, header compression, and multiplex requests over a single TCP connection. These features allow it to perform better on mobile devices, saving power and space.

The following describes GRPC concepts

What is GRPC?

In gRPC, the client application can call the methods of the server application on another machine as directly as the local method, which makes it easy to create distributed applications and services. Like other RPC systems, gRPC is based on the idea of first defining a service that defines methods (including parameters and return types) that can be called remotely. Implement this method on the server side and run a gRPC server to handle the client calls. On the client side, you have a stub, which is a method that looks like the server (but is not implemented), through which the client invokes the server’s methods.

The working principle of GRPC is as follows:

Protocol used by GRPC

GRPC uses Protocol buffers by default, a mature serialization mechanism for structured data that is open-source by Google. Other data formats such as JSON can also be used, but protocol buffers are often used as a flexible and efficient data format. If you do not understand protobuf syntax, click here for the Protocol Buffers introductory tutorial.

The service definition

With GPRC, you first need to define the service, specifying the methods that can be called remotely with their parameters and return types.

A service, you can think of as a collection of server-side apis that provide some external functionality.

Example of defining a service with protobuf:

// Define a method called SayHello that takes a HelloRequest message as an argument, RPC SayHello (HelloRequest) returns (HelloResponse); Message HelloRequest {string greeting = 1; Message HelloResponse {string reply = 1; }Copy the code

If you think of the service and message keywords as classes, it looks like a class definition!

GRPC allows you to define four classes of service methods. Here’s how to define them and how the client and server interact.

One-way RPC

That is, the client sends a request to the server and gets a response from the server, just like a normal function call.

rpc SayHello(HelloRequest) returns (HelloResponse){
}
Copy the code

Server-side streaming RPC

That is, the client sends a request to the server to obtain a data stream to read a series of messages. The client reads from the returned data stream until there are no more messages.

Generally speaking, the client requests once, and the server can continuously send messages to the client.

RPC LotsOfReplies(HelloRequest) returns (stream HelloResponse){}Copy the code

Client-side streaming RPC

That is, the client writes and sends a series of messages to the server using a provided data stream. Once the client has finished writing the messages, it waits for the server to read them and return a reply.

In layman’s terms, the client can send messages to the server continuously after a request is made.

RPC LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}Copy the code

Two-way streaming RPC

That is, each side can send a series of messages through a read/write data stream. The two data flow operations are independent of each other, so the client and server can read and write in any order they wish. For example, the server can wait for all client messages before writing a reply, or it can read one message and then write another, or some other combination of read and write. The order of messages in each data stream is maintained.

Similar to TCP communication, the client and server can send messages to each other.

RPC BidiHello(stream HelloRequest) returns (stream HelloResponse){}Copy the code

More on GRPC tutorials can be found here

Write the Go-Micro HTTP service

Install the gofast plug-in

//gofast
go get -u -v github.com/gogo/protobuf/protoc-gen-gofast
Copy the code

Start writing the Go-Micro HTTP service

Create the Go-Micro-examples directory, and create the HelloWorld directory under that directory

inhelloworldIn the directory, create aprotohandlerAnd create main.go and initialize the project with Go mod init, as shown in the figure below

Other files are ignored for the moment and will be explained later

Create helloWorld.proto in the proto directory and write the following code

syntax = "proto3"; package helloworld; option go_package = "proto; helloworld"; service Helloworld { rpc Call(Request) returns (Response) {} rpc Stream(StreamingRequest) returns (stream StreamingResponse) {} rpc PingPong(stream Ping) returns (stream Pong) {} } message Message { string say = 1; } message Request { string name = 1; } message Response { string msg = 1; } message StreamingRequest { int64 count = 1; } message StreamingResponse { int64 count = 1; } message Ping { int64 stroke = 1; } message Pong { int64 stroke = 1; }Copy the code

Enter the directory and enter the following command

And generatehelloworld.pb.go,helloworld.pb.micro.go

In main.go, create the service and register a handler to run the service

package main

import (
	"github.com/asim/go-micro/v3"
	"github.com/asim/go-micro/v3/logger"
	"go-micro-examples/helloworld/handler"
	pb "go-micro-examples/helloworld/proto"
)

const (
	ServerName = "go.micro.srv.HelloWorld" // server name
)

func main(a) {
	// Create service
	service := micro.NewService(
		micro.Name(ServerName),
		micro.Version("latest"),// Register handler
	if err := pb.RegisterHelloworldHandler(service.Server(), new(handler.Helloworld)); err ! =nil {
		logger.Fatal(err)
	}

	// Run service
	iferr := service.Run(); err ! =nil {
		logger.Fatal(err)
	}
}
Copy the code

The client to invoke the service

Create the client directory and create client.go. Write the following code

package main

import (
	"context"
	"fmt"
	"github.com/asim/go-micro/v3"
	helloworld "go-micro-examples/helloworld/proto"
)

func main(a) {
	// create a new service
	service := micro.NewService()

	// parse command line flags
	service.Init()

	// Use the generated client stub
	cl := helloworld.NewHelloworldService("go.micro.srv.HelloWorld", service.Client())

	// Make request
	rsp, err := cl.Call(context.Background(), &helloworld.Request{
		Name: "John",})iferr ! =nil {
		fmt.Println(err)
		return
	}
	fmt.Println(rsp.Msg)
}
Copy the code

The effect

To enable thego.micro.srv.HelloWorldService, and then start againclientCall with the following effect

After starting the client, print Hello World!

Refer to the link

  • ProtoBuf tutorial
  • GRPC framework tutorial