go micro实战01:快速搭建服务
source link: http://www.cnblogs.com/enochzzg/p/12582646.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
背景
go-micro给我们提供了一个非常便捷的方式来快速搭建微服务,而且并不需要提前系统了解micro,下面用一个简单的示例来快速实现一个服务。
创建Proto文件
因为我们要做微服务,那么就一定有服务端和客户端,这两个端通过什么格式进行内容传输,就涉及到了序列化,比较主流的序列化协议就是JSON和Protobuf,因为Protobuf是以二进制传输的,体积比较小,所以传输速度也相对较快,今天就以protobuf来进行演示。
下面使用Proto3的语法在protos目录创建文件 greeter.proto
,该文件定义一个名为 Greeter
的服务,以及对应的入参和出参。
syntax = "proto3"; package protos; service Greeter { rpc Hello (Request) returns (Response) { }; } message Request { string name = 1; } message Response { string greeting = 2; }
生成Go文件
生成Go文件之前,要先确保本机安装了protobuf,如果在终端输入 protoc
没有打印出帮助文档,那么就是未安装。
$ 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 ……
可以通过官方文档提示的命令进行安装。
go get github.com/micro/protoc-gen-micro/v2
安装成功之后,通过protoc命令将 greeter.proto
文件生成出对应的Go文件。
protoc --proto_path=./protos --micro_out=./protos --go_out=./protos ./protos/greeter.proto
-
--proto_path
是greeter.proto文件所在的路径 -
--micro_out
是生成.go
文件的所在目录,该文件被用于创建服务 -
--go_out
是生成.go
文件的所在目录,该文件被用于做数据序列化传输
可以根据需求自定义输出目录,我这边输出到了protos目录,现在可以看到protos目录中生成了两个文件。
greeter.pb.go greeter.pb.micro.go
实现服务
因为刚才已经通过protobuf定义了服务的接口,所以接下来需要实现对应的服务。
第一步,实现定义的服务接口
在生成的 greeter.pb.micro.go
文件中,可以看到我们 greeter.proto
文件中一个名为 GreeterHandler
的接口。
type GreeterHandler interface { Hello(context.Context, *Request, *Response) error }
我们需要先实现该接口,接下来创建server.go文件,定义结构体Greeter,并实现Hello方法。
type Greeter struct { } func (g *Greeter) Hello(context context.Context, req *protos.Request, rsp *protos.Response) error { rsp.Greeting = "Hello " + req.Name return nil }
Hello方法的后两个参数刚好就是我们前面所生成的 greeter.bp.go
文件中定义的Request和Response结构体。在方法内部,将请求参数的Name前面拼接上了 Hello
字符串,并且赋值给了Response的Greeting变量。
第二步,初始化服务
我们创建一个名为 greeter
的服务。
func main() { service := micro.NewService( micro.Name("greeter"), ) service.Init() }
调用 micro.NewService
方法来创建一个新的服务,该方法的参数是可变参数,可以通过micro中的一系列方法来设置服务的参数,本次示例中只配置服务的名称,记得在创建完服务后执行 service.Init
方法来初始化,micro版本建议使用v2。
第三步,注册服务到handler
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) }
完整代码如下
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) } }
现在将服务端跑起来。
$ 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
实现客户端
创建 client.go
文件
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) }
执行客户端文件,输出 Hello pingye
,执行成功。
$ go run client.go Hello pingye
服务注册到了哪里?
在启动服务端的时候从终端输出的信息可以看出,有一个名为 greeter
的服务注册到了 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是go-micro的注册模块,作用是将服务注册到某个介质,以方便客户端使用。注册模块默认支持cache、consul、etcd、k8s、mdns、memory等多种介质,默认使用的是mdns。
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主要用于在没有传统DNS服务器的情况下,在局域网中实现主机之间的发现与通讯,它遵从DNS协议。
Go语言组件示例开源库,欢迎star
https://github.com/EnochZg/golang-examplesRecommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK