见下文:一文入门Go云原生微服务「爆肝6千字」一+地址链接:https://developer.aliyun.com/article/1393833
准备工作
1. 安装micro v2
#安装go-micro go get github.com/micro/go-micro/v2 #安装工具集 go get github.com/micro/micro/v2
2. 安装protobuf插件
#安装protobuf go get github.com/golang/protobuf/{proto,protoc-gen-go} #指定版本安装生成micro代码的工具集 go get github.com/micro/micro/v2/cmd/protoc-gen-micro
我们在编写proto文件之后,使用protoc-gen-go自动生成代码,所以需要提前安装好依赖。
3. 创建项目结构
我们在合适的目录创建项目目录,比如我选择在我的Go安装目录/Users/wangzhongyang/go/src/
新建go-micro目录,用于统一管理go-micro相关的项目。
cd /Users/wangzhongyang/go/src/ mkdir go-micro
在go-micro目录下创建helloworld目录,用于编写本次的演示项目。
cd go-micro mkdir helloworld cd helloworld
在helloworld目录下新建proto目录用于编写proto文件,另外创建main.go文件作为服务的入口文件:
touch main.go mkdir proto
准备工作做好之后,下面开发微服务的步骤和“开发gRPC总共分三步”是一样的:
- 写proto文件定义服务和消息
- 使用protoc工具生成代码
- 编写业务逻辑代码提供服务
1. 编写proto文件
我们在helloword/proto目录下 新建greeter.proto文件
编写proto文件和用什么微服务框架没有关系,我们都需要定义syntax、service和message
syntax = "proto3"; //pb是protoc 生成go文件的包名 option go_package ="./;pb"; service Greeter { rpc Hello(Request) returns (Response) {} } message Request { string name = 1; } message Response { string greeting = 1; }
2. 使用protoc工具生成代码
我们打开控制台,切换到proto目录下,比如我的目录是:
cd /Users/wangzhongyang/go/src/go-micro/helloworld/proto
执行自动生成代码命令:
注意:我们必须使用带有 micro plugin 的 protoc 编译它。
protoc --proto_path=. --micro_out=. --go_out=. greeter.proto
我们发现执行上述命令后,生成了pb.go文件和pb.micro.go文件。
但是有报错,不用担心,接着往下看:
2.1 解决报错
报错原因是因为没有导入依赖,我们在项目根目录下执行:
go mod init go mod tidy
同步依赖后,发现报错消失了:
3. 编写业务逻辑代码提供服务
3.1 编写服务端
- 我们直接在main.go中编写服务
- import中的 proto 对应的目录改成自己的。你自己的module名称可以在go.mod中查看:
- 关键代码已加注释,逻辑和# 开发gRPC总共分三步 的入门实践部分非常像。
package main import ( "context" "fmt" micro "github.com/micro/go-micro/v2" proto "go-micro/helloworld/proto" //注意这里:修改成你自己的 ) //定义结构体 作为方法调用方 type Greeter struct{} //实现 .pb.micro.go中的Hello方法 定义rsp的返回值 func (g *Greeter) Hello(ctx context.Context, req *proto.Request, rsp *proto.Response) error { rsp.Greeting = "Hello " + req.Name return nil } func main() { //定义服务 service := micro.NewService( micro.Name("greeter"), ) //服务初始化 service.Init() // 注册handler err := proto.RegisterGreeterHandler(service.Server(), new(Greeter)) if err != nil { return } //启动服务 if err := service.Run(); err != nil { fmt.Println(err) } }
服务端编写好之后我们再编写客户端:
3.2 编写客户端
在项目根目录下,新建client目录,新建client.go文件,用于编写客户端代码
创建目录和文件:
mkdir client cd client touch client.go
编写代码:
- 关键逻辑已经添加注释
- NewGreeterService()和Hello()都是proto文件自动生成的的,定义在.pb.micro文件中
package main import ( "context" "fmt" micro "github.com/micro/go-micro/v2" proto "go-micro/helloworld/proto" ) func main() { //创建一个新的服务 命名 service := micro.NewService(micro.Name("greeter.client")) //服务初始化 service.Init() //创建服务 绑定客户端 这个方法是在proto生成的文件中定义的 greeter := proto.NewGreeterService("greeter", service.Client()) //调用Hello方法 Hello方法同样是在proto生成的文件中定义的 rsp, err := greeter.Hello(context.TODO(), &proto.Request{Name: "World"}) if err != nil { fmt.Println(err) } //打印结果 fmt.Println(rsp.Greeting) }
我们来看一下 .pb.micro.go文件的源码, 重点看一下Hello方法:
到这里我们就编码完毕,看下执行效果:
3.3 启动服务,进行调用
1.先启动服务端
我们打开控制台,切换到项目根目录下,执行命令:
go run main.go
执行效果如下,服务端已经启动:
2.再启动客户端
我们另外打开一个控制台,启动客户端服务:
cd go-micro/helloworld/client/ go run client.go
执行效果如下,和我们预期的效果一样,成功的打印出了Hello World:
总结
分布式微服务架构已成趋势,越来越多的公司在从单体应用或集中式应用向分布式应用转型。开篇类比了主流Go微服务框架的特点,Go的微服务生态可以说是百家争鸣。
本文也介绍了微服务的特点和优势,go-micro的架构和构成组件;类比原生开发rpc项目,用go-micro实现了经典的Hello World问候服务,带大家入门了微服务开发。
关于专栏
近期会更新一系列Go实战进阶的文章,欢迎大家关注我的:# Go语言进阶实战专栏。
这是近期会更新文章的知识脉络图,感兴趣的小伙伴可以关注一波,欢迎日常催更。
微信号:wangzhongyang1993 公众号:程序员升职加薪之旅 B站视频:王中阳Go