分享
  1. 首页
  2. 文章

Go实践微服务 -- 服务发现

Ryan是菜鸟 · · 5042 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

服务的注册发现对于微服务来说是一个非常重要的环节,在单一架构应用中,service之间的互相调用,通过一个固定的host和port来发起REST或者RPC来调用,但是在微服务架构中,各个服务往往是动态变化的,所以需要一个服务发现机制来发送客户端的请求到动态的service实例中去。

在利用go micro来实现服务发现便利很多,micro中默认支持使用 Consul 来做服务发现,当然它使用插件机制(go-plugins)还支持 Etcd, Gossip, NATS等其他的第三方服务注册发现工具。在每个服务启动的时候,都将自己注册到registry上,退出时也自动解注册,具体实现我们可以来看一下go-micro/service.go的相关代码片段:

......
func (s *service) run(exit chan bool) {
 if s.opts.RegisterInterval <= time.Duration(0) {
 return
 }
 //定时注册自己
 t := time.NewTicker(s.opts.RegisterInterval)
 for {
 select {
 case <-t.C:
 err := s.opts.Server.Register()
 if err != nil {
 log.Log("service run Server.Register error: ", err)
 }
 case <-exit:
 t.Stop()
 return
 }
 }
}
......
func (s *service) Start() error {
 for _, fn := range s.opts.BeforeStart {
 if err := fn(); err != nil {
 return err
 }
 }
 if err := s.opts.Server.Start(); err != nil {
 return err
 }
 // Run() 调用中也会结果run来调到这里来注册
 if err := s.opts.Server.Register(); err != nil {
 return err
 }
 for _, fn := range s.opts.AfterStart {
 if err := fn(); err != nil {
 return err
 }
 }
 return nil
}
func (s *service) Stop() error {
 var gerr error
 for _, fn := range s.opts.BeforeStop {
 if err := fn(); err != nil {
 gerr = err
 }
 }
 // 退出时自动解除注册
 if err := s.opts.Server.Deregister(); err != nil {
 return err
 }
 if err := s.opts.Server.Stop(); err != nil {
 return err
 }
 for _, fn := range s.opts.AfterStop {
 if err := fn(); err != nil {
 gerr = err
 }
 }
 return gerr
}
......

关于Consul的相关使用可以参考 《Consul 简介和快速入门》,下面主要来利用一个酒店预订的示例来看下Go Micro如何使用Consul的集群来做服务发现。

示例中会使用到一个 Micro API,它是Micro组件中的一个微服务API网关的实现,API网关模式可以为服务提供一个入口,该HTTP入口动态路由到合适的后端service,利用它进行服务发现,负载平衡,编码和基于RPC的通信。

api

Micro API提供的HTTP API 如下 :

- /[service]/[method] # HTTP路径动态映射到services
- /rpc # 通过名称和方法显示调用后端service

在示例中使用 Micro API 的 RPC Handler,它是go-micro客户端将请求主体转发为RPC请求的默认处理程序的替代方案,具体Micro API的使用和REST映射规则可以查看文档https://micro.mu/docs/api.html

该酒店预定服务利用了官方 micro/examples中的booking示例改写, 具体代码 => https://github.com/yuansir/go...

.
├── README.md
├── api
│  └── hotel # booking service
├── data # data
│  ├── bindata.go
│  ├── customers.json
│  ├── locations.json
│  ├── profiles.json
│  └── rates.json
├── docker-compose.yml # docker compose file
└── srv # services
 ├── auth # auth token servce
 ├── geo # geo service
 ├── profile # profile service
 └── rate # rate service

docker-compose.yml

version: '3'
services:
 consul-agent-1: &consul-agent
 image: consul:latest
 networks:
 - consul-cluster
 command: "agent -retry-join consul-server-bootstrap -client 0.0.0.0"
 consul-agent-2:
 <<: *consul-agent
 consul-agent-3:
 <<: *consul-agent
 consul-server-1: &consul-server
 <<: *consul-agent
 command: "agent -server -retry-join consul-server-bootstrap -client 0.0.0.0"
 consul-server-2:
 <<: *consul-server
 consul-server-bootstrap:
 <<: *consul-agent
 ports:
 - "8400:8400"
 - "8500:8500"
 - "8600:8600"
 - "8600:8600/udp"
 command: "agent -server -bootstrap-expect 3 -ui -client 0.0.0.0"
 auth:
 build: ./srv/auth
 networks:
 - consul-cluster
 command: --registry_address=consul-server-bootstrap:8500
 links:
 - consul-server-bootstrap
 geo:
 build: ./srv/geo
 networks:
 - consul-cluster
 command: --registry_address=consul-server-bootstrap:8500
 links:
 - consul-server-bootstrap
 profile:
 build: ./srv/profile
 networks:
 - consul-cluster
 command: --registry_address=consul-server-bootstrap:8500
 links:
 - consul-server-bootstrap
 rate:
 build: ./srv/rate
 networks:
 - consul-cluster
 command: --registry_address=consul-server-bootstrap:8500
 links:
 - consul-server-bootstrap
 api:
 build: ./api/hotel
 networks:
 - consul-cluster
 command: --registry_address=consul-server-bootstrap:8500
 links:
 - consul-server-bootstrap
 - auth
 - geo
 - profile
 - rate
 micro:
 networks:
 - consul-cluster
 command: --registry_address=consul-server-bootstrap:8500 api --handler=rpc
 image: microhq/micro:latest
 links:
 - consul-server-bootstrap
 - api
 ports:
 - "8080:8080"
networks:
 consul-cluster:

consul每个数据中心至少必须拥有一台server,建议在一个集群中有3或者5个server.部署单一的server,在出现失败时会不可避免的造成数据丢失.-bootstrap-expect 选项提示Consul我们期待加入的server节点的数量。每一个服务的--registry_address就是设置注册到的服务发现注册表地址。

docker-compose up 后可以通过consul 的web ui来查看Service的状态。
1531203571067

转载请注明: 转载自Ryan是菜鸟 | LNMP技术栈笔记

如果觉得本篇文章对您十分有益,何不 打赏一下

本文链接地址: Go实践微服务 -- 服务发现


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:Ryan是菜鸟

查看原文:Go实践微服务 -- 服务发现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
5042 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏