分享
  1. 首页
  2. 文章

go-micro+gin+consul微服务实战之服务注册与发现

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

在构建微服务时,使用服务发现可以减少配置的复杂性,本文以go-micro为微服务框架,使用consul作为服务发现服务,使用gin开发golang服务。

使用gin 的原因是gin能够很好的和go-micro进行集成。

本文主要介绍服务注册和发现的实现

关于如何搭建consul服务可以移步:https://www.jianshu.com/p/271d490929a5

本文默认以搭建好了consul服务,服务的地址是:192.168.109.131:8500
如果你搭建好了自己的consul服务,可以在浏览器内输入192.168.109.131:8500(地址根据自己的consul服务做调整),会看到如下界面:


图片.png

这里我的consul服务启用了 3个节点。

填坑

在开始写代码前,先给大家避一避坑,目前go-micro已经更新到v2版本,此版本去除了对consul 的支持,但支持etcd、mdns作为服务发现,但是老版本的go-micro仍支持consul,但是有些地方做了调整。

首先,需要go 1.13的支持,所以小伙伴们需要升级下golang
然后,在获取go-micro库时,不能使用这个指令了 go get -u github.com/micro/go-micro
 改为:go get -u github.com/micro/go-micro/v2
原来go-micro consul的支持已经迁移到了go-plugins里面
我们的代码里在导入consul库时,也变为了:
"github.com/micro/go-plugins/registry/consul"
这个在下面的代码里可以看到
然后,没有安装gin的同学,需要使用如下指令获取下:
go get -u github.com/gin-gonic/gin

这些小编折腾了很久才搞明白,这里先给大家提醒下,避免走我的老路

开撸

服务注册

我们预设两个server,userserver和orderserver
下面开始上代码:
userserver程序结果如下:

图片.png

有两个文件router.go和main.go
main.go代码如下
main.go实现初始化路由,服务注册
package main
import (
 "github.com/micro/go-micro/registry"//注意这些地址变了
 "github.com/micro/go-micro/web"//注意这些地址变了
 "github.com/micro/go-plugins/registry/consul"//注意这些地址变了
 "userserver/routers"
)
var consulReg registry.Registry
func init() {
 //新建一个consul注册的地址,也就是我们consul服务启动的机器ip+端口
 consulReg = consul.NewRegistry(
 registry.Addrs("192.168.109.131:8500"),
 )
}
func main() {
 //初始化路由
 ginRouter := routers.InitRouters()
 //注册服务
 microService:= web.NewService(
 web.Name("userserver"),
 //web.RegisterTTL(time.Second*30),//设置注册服务的过期时间
 //web.RegisterInterval(time.Second*20),//设置间隔多久再次注册服务
 web.Address(":18001"),
 web.Handler(ginRouter),
 web.Registry(consulReg),
 )
 microService.Run()
}

router.go代码如下
router.go主要用来定义程序的api接口,使用gin开发

package routers
import "github.com/gin-gonic/gin"
func InitRouters() *gin.Engine {
 ginRouter := gin.Default()
 ginRouter.POST("/users/", func(context *gin.Context) {
 context.String(200, "get userinfos")
 })
 return ginRouter
}

注册的代码就写好了,启动userserver,我们在consul服务界面,可以看到如下效果:


图片.png

说明我们注册成功了

服务发现

服务发现,就是从consul中获取到我们注册进去的服务,这样在调用别的服务时,就不用从配置文件获取,直接查询consul即可。

orderserver我们除了实现服务注册外,也实现服务发现的功能
orderserver代码结构如下:


图片.png

上代码
main.go代码如下

package main
import (
 "bytes"
 "fmt"
 "github.com/micro/go-micro/client/selector"
 "github.com/micro/go-micro/registry"
 "github.com/micro/go-micro/web"
 "github.com/micro/go-plugins/registry/consul"
 "net/http"
 "orderserver/routers"
 "time"
)
var consulReg registry.Registry
func init(){
 //新建一个consul注册的地址,也就是我们consul服务启动的机器ip+端口
 consulReg = consul.NewRegistry(
 registry.Addrs("192.168.109.131:8500"),
 )
}
func main() {
 //初始化路由
 ginRouter := routers.InitRouters()
 //注册服务
 microService:= web.NewService(
 web.Name("orderserver"),
 //web.RegisterTTL(time.Second*30),//设置注册服务的过期时间
 //web.RegisterInterval(time.Second*20),//设置间隔多久再次注册服务
 web.Address(":18002"),
 web.Handler(ginRouter),
 web.Registry(consulReg),
 )
 //获取服务地址
 hostAddress := GetServiceAddr("userserver")
 if len(hostAddress) <= 0{
 fmt.Println("hostAddress is null")
 }else{
 url := "http://"+ hostAddress + "/users"
 response, _ := http.Post(url, "application/json;charset=utf-8",bytes.NewBuffer([]byte("")))
 fmt.Println(response)
 }
 microService.Run()
}
func GetServiceAddr(serviceName string)(address string){
 var retryCount int
 for{
 servers,err :=consulReg.GetService(serviceName)
 if err !=nil {
 fmt.Println(err.Error())
 }
 var services []*registry.Service
 for _,value := range servers{
 fmt.Println(value.Name, ":", value.Version)
 services = append(services, value)
 }
 next := selector.RoundRobin(services)
 if node , err := next();err == nil{
 address = node.Address
 }
 if len(address) > 0{
 return
 }
 //重试次数++
 retryCount++
 time.Sleep(time.Second * 1)
 //重试5次为获取返回空
 if retryCount >= 5{
 return
 }
 }
}

GetServiceAddr就是服务发现的代码

首先,使用servers,err :=consulReg.GetService(serviceName)获取注册的服务
返回的servers是个slice
然后,使用next := selector.RoundRobin(services)获取其中一个服务的信息
这里注意:
在老版本中可以直接使用selector.RoundRobin(services),但是在v2版本中需要做个转换处理:
var services []*registry.Service
for _,value := range servers{
 fmt.Println(value.Name, ":", value.Version)
 services = append(services, value)
}
因为使用的数据结构不同,感兴趣的可以细看下区别。

router.go代码如下

package routers
import "github.com/gin-gonic/gin"
func InitRouters() *gin.Engine {
 ginRouter := gin.Default()
 ginRouter.POST("/orders/", func(context *gin.Context) {
 context.String(200, "get orderinfos")
 })
 return ginRouter
}

启动oerderserver 我们就能获取到userserver的地址,各位可以调试看下效果。

今天go-micro+gin+consul微服务实战就介绍完了,是不是很简单


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

本文来自:简书

感谢作者:技术修仙

查看原文:go-micro+gin+consul微服务实战之服务注册与发现

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

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

用户登录

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

今日阅读排行

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

一周阅读排行

    加载中

关注我

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

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

给该专栏投稿 写篇新文章

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

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