不忘初心,砥砺前行
作者 | 莫无崖
转载请联系授权
上一篇文章中有了入门案例,现在是不是有了很好的理解,不过有个前提是你需要了解grpc技术,简单的来说grpc是一个通信框架,micro是类似的一个通信框架,只不过这个框架应用于微服务中。因此如果你还未了解grpc技术,仍然建议你学习grpc基础,便于更好的理解本篇文章。
1## 安装go-micro 2go get github.com/micro/go-micro 3## 安装micro 4go get github.com/micro/micro 5## 安装grpc 6go get -u google.golang.org/grpc 7## 安装grpc插件 8go get -u github.com/golang/protobuf/protoc-gen-go 9## 安装micro插件 10go get github.com/micro/protoc-gen-micro 11# 设置环境变量,便于命令行操作 12export PATH=$PATH:$GOPATH/bin
如果你做过web开发,Http请求是无法避免的,服务端需要接受请求并返回相应的结果,但是这种情况下,如何才能在Go Micro中实现呢?其实在Micro中官方为我们提供了API网关micro api。对API的请求将有HTTP提供,并通过服务发现我们的路由。简单来说使用API网关模式为你的服务提供单个公共入口点。micro api服务于HTTP并使用服务发现动态路由。由于micro api基于go-micro开发,因此它同时具备了服务发现,负载均衡等能力。是可插拔的一个微服务。
启动
1micro api [command options] [arguments...]
options选项
--address:用来设置api地址,例如:0.0.0.0:8080
--handler:用来指定用于将HTTP请求映射到服务的请求处理程序,值有四个:api,event,http,rpc。
--namespace:设置api的命名空间,例如:go.micro.api,使用这个之后,http请求之后,才会解析api所在的路由
--resolver:设置api使用的主机名解析程序,值有三个:host,path,grpc。
服务端
定义api.proto,这里需要注意的是我们定义了两个服务分别是Example 和 Foo,下面模拟Http请求结构体,其实Go-micro直接为我们封装了这部分如图
这里我们只是贴上源码,方便大家理解。
1syntax = "proto3"; 2 3package go.micro.api.example; 4 5service Example { 6 rpc Call(Request) returns(Response); 7} 8 9service Foo { 10 rpc Bar(Request) returns(Response); 11} 12 13 14message Pair { 15 string key = 1; 16 repeated string values = 2; 17} 18// 一个Http请求 19message Request { 20 string method = 1; 21 string path = 2; 22 map<string, Pair> header = 3; 23 map<string, Pair> get = 4; 24 map<string, Pair> post = 5; 25 string body = 6; 26 string url = 7; 27} 28// 一个Http响应 29message Response { 30 int32 statusCode = 1; 31 map<string, Pair> header = 2; 32 string body = 3; 33} 34// 一个Http事件 35message Event { 36 // e.g login 37 string name = 1; 38 // uuid 39 string id = 2; 40 // unix timestamp of event 41 int64 timestamp = 3; 42 // event headers 43 map<string, Pair> header = 4; 44 // the event data 45 string data = 5; 46}
编写我们的服务端代码
1type Example struct{} 2 3type Foo struct{} 4 5// Example.Call 通过API向外暴露为/example/call,接收http请求 6func (e *Example) Call(ctx context.Context, req *api.Request, rsp *api.Response) error { 7 log.Log("Example.Call接口收到请求") 8 //获取参数 map[string]*api.Pair数据类型 9 name, ok := req.Get["name"] 10 // 判断 values数组是否存在值 11 if !ok || len(name.Values) == 0 { 12 return errors.BadRequest("go.micro.api.example", "参数不正确") 13 } 14 15 // 打印请求头 16 for k, v := range req.Header { 17 log.Log("请求头信息,", k, " : ", v) 18 } 19 20 rsp.StatusCode = 200 21 22 b, _ := json.Marshal(map[string]string{ 23 "message": "我们已经收到你的请求," + strings.Join(name.Values, " "), 24 }) 25 26 // 设置返回值 27 rsp.Body = string(b) 28 29 return nil 30} 31// 32func (f *Foo) Bar(ctx context.Context, req *api.Request, rsp *api.Response) error { 33 log.Logf("Foo.Bar接口收到请求") 34 //判断请求方法是否是POST 35 if req.Method != "POST" { 36 return errors.BadRequest("go.micro.api.example", "require post") 37 } 38 //获得请求头 39 ct, ok := req.Header["Content-Type"] 40 if !ok || len(ct.Values) == 0 { 41 return errors.BadRequest("go.micro.api.example", "need content-type") 42 } 43 44 fmt.Println(ct.Values[0]) 45 if ct.Values[0] != "application/json" { 46 return errors.BadRequest("go.micro.api.example", "expect application/json") 47 } 48 49 var body map[string]interface{} 50 json.Unmarshal([]byte(req.Body), &body) 51 52 // 设置返回值 53 rsp.Body = "收到消息:" + string([]byte(req.Body)) 54 55 return nil 56}
注册我们的服务,这里和之前方法类似,不再强调。
1service := micro.NewService( 2 micro.Name("go.micro.api.example"), 3 micro.Version("latest"), 4 ) 5 6 service.Init() 7 // 注册 example handler 8 api.RegisterExampleHandler(service.Server(), new(Example)) 9 10 // 注册 foo handler 11 api.RegisterFooHandler(service.Server(), new(Foo)) 12 13 if err := service.Run(); err != nil { 14 log.Fatal(err) 15 }
首先启动我们的api
1micro api --handler=api --namespace=go.micro.api
启动我们的服务端
1go run api.go
我们这里用postman进行测试如下
测试bar
测试example
查看我们的控制台,同样产生了信息
掌握本篇知识,总体来说不是很难,阅读时,请耐心思考,自己多加实践,才能更好的掌握。
本篇文章参考Go-Mico官方博客和系列案例进行总结分享。
END
今日推荐阅读
RabbitMQ系列笔记广播模式和路由模式
RabbitMQ系列笔记入门篇RabbitMQ系列笔记work模式
RabbitMQ系列笔记work模式
protoc语法详解及结合grpc定义服务
Golang中Model的使用
基于Nginx和Consul构建高可用及自动发现的Docker服务架构
▼关注我,一起成长
主要分享 学习心得、笔记、随笔▼