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