go micro practice 01: fast build service

background

Go micro provides us with a very convenient way to quickly build microservices, and we do not need to know about micro in advance. Here is a simple example to quickly implement a service.

Create a Proto file

Because we want to do microservices, there must be a server and a client. The format of content transmission between these two ends involves serialization. The mainstream serialization protocols are JSON and protobuf. Because protobuf is transmitted in binary and has a smaller volume ratio, the transmission speed is relatively fast. Today, protobuf is used for demonstration.

Next, use the syntax of Proto3 to create the file greeter.proto in the protos directory, which defines a service named Greeter and the corresponding input and output parameters.

syntax = "proto3";
package protos;

service Greeter {
    rpc Hello (Request) returns (Response) {
    };
}

message Request {
    string name = 1;
}

message Response {
    string greeting = 2;
}

Generate Go file

Before generating the Go file, make sure that protobuf is installed on the machine. If you input protoc on the terminal and do not print out the help document, it is not installed.

$ protoc
Usage: protoc [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
  -IPATH, --proto_path=PATH   Specify the directory in which to search for
                              imports.  May be specified multiple times;
                              directories will be searched in order.  If not
                              ......

It can be installed by the command prompted in the official document.

go get github.com/micro/protoc-gen-micro/v2

After the installation is successful, use the protoc command to generate the corresponding Go file from the greeter.proto file.

protoc --proto_path=./protos --micro_out=./protos --go_out=./protos ./protos/greeter.proto
  • --Proto u path is the path where the greeter.proto file is located

  • --Micro Ou out is the directory where the. go file is generated, which is used to create the service

  • --go out is the directory where the. go file is generated, which is used for data serialization and transmission

You can customize the output directory according to your needs. I output to the protos directory. Now you can see that two files are generated in the protos directory.

greeter.pb.go
greeter.pb.micro.go

Implementation service

Because the service interface has been defined through protobuf just now, the corresponding service needs to be implemented next.

The first step is to implement the defined service interface

In the generated greeter.pb.micro.go file, you can see an interface named greerhandler in our greeter.proto file.

type GreeterHandler interface {
	Hello(context.Context, *Request, *Response) error
}

We need to implement the interface first, then create the server.go file, define the structure Greeter, and implement the Hello method.

type Greeter struct {
}

func (g *Greeter) Hello(context context.Context, req *protos.Request, rsp *protos.Response) error {
	rsp.Greeting = "Hello " + req.Name
	return nil
}

The last two parameters of the Hello method are just the Request and Response structures defined in the greeter.bp.go file we generated earlier. Inside the method, the Name of the Request parameter is spliced with a hello string and assigned to the Greeting variable of the Response.

Step 2, initialize the service

We create a service called greeter.

func main() {
	service := micro.NewService(
		micro.Name("greeter"),
	)
	service.Init()
}

Call the micro.NewService method to create a new service. The parameters of this method are variable parameters. You can set the parameters of the service through a series of methods in micro. In this example, only the name of the service is configured. Remember to execute the service.Init method to initialize after creating the service. v2 is recommended for micro version.

Step 3: register the service to the handler

func main() {
	service := micro.NewService(
		micro.Name("greeter"),
	)
	service.Init()
	err := protos.RegisterGreeterHandler(service.Server(), new(Greeter))
	if err != nil {
		fmt.Println(err)
	}
}

Step 4: run the service

	if err := service.Run(); err != nil {
		fmt.Println(err)
	}

The complete code is as follows

package main

import (
	"context"
	"fmt"

	"github.com/micro/go-micro/v2"
)

type Greeter struct {
}

func (g *Greeter) Hello(context context.Context, req *Request, rsp *Response) error {
	rsp.Greeting = "Hello " + req.Name
	return nil
}

func main() {
	service := micro.NewService(
		micro.Name("greeter"),
	)
	service.Init()

	err := protos.RegisterGreeterHandler(service.Server(), new(Greeter))
	if err != nil {
		fmt.Println(err)
	}

	if err := service.Run(); err != nil {
		fmt.Println(err)
	}
}

Now run the server.

$ go run server.go
2020-03-27 11:28:20 Starting [service] greeter
2020-03-27 11:28:20 Server [grpc] Listening on [::]:63763
2020-03-27 11:28:20 Registry [mdns] Registering node: greeter-8afc1183-a159-4473-a567-c13b83d1d75c

Implement client

Create the client.go file

func main() {
	service := micro.NewService(micro.Name("greeter.client"))
	service.Init()

	greeter := protos.NewGreeterService("greeter", service.Client())
	rsp, err := greeter.Hello(context.TODO(), &protos.Request{Name: "pingye"})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(rsp.Greeting)
}

Execute the client file and output Hello pingye. The execution is successful.

$ go run client.go
Hello pingye

Where is the service registered?

When starting the server, you can see from the information output by the terminal that there is a service named greeter registered in the Registry.

2020-03-27 11:28:20 Starting [service] greeter
2020-03-27 11:28:20 Server [grpc] Listening on [::]:63763
2020-03-27 11:28:20 Registry [mdns] Registering node: greeter-8afc1183-a159-4473-a567-c13b83d1d75c

Registry is the registration module of go micro, which is used to register services to a certain medium for the convenience of clients. The registration module supports cache, consumer, etcd, k8s, mdns, memory and other media by default, and mdns is used by default.

var (
	DefaultRegistry = NewRegistry()

	// Not found error when GetService is called
	ErrNotFound = errors.New("service not found")
	// Watcher stopped error when watcher is stopped
	ErrWatcherStopped = errors.New("watcher stopped")
)

mdns is mainly used to realize the discovery and communication between hosts in LAN without traditional DNS server. It complies with DNS protocol.

Go language component sample open source library, welcome star
https://github.com/EnochZg/golang-examples

Keywords: Go github DNS JSON

Added by BMorganVA on Fri, 27 Mar 2020 12:21:40 +0200