Go 实现Consul服务发现注册

513 阅读2分钟

Consul介绍

       Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案。使用起来也较 为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

Consul特性

  • 服务发现:利用服务注册,服务发现功能来实现服务治理。
  • 健康检查:利用consul注册的检查检查函数或脚本来判断服务是否健康,若服务不存在则从注册中心移除该服务,减少故障服务请求。
  • k/v数据存储:存储kv数据,可以作为服务配置中心来使用。
  • 多数据中心:可以建立多个consul集群通过inter网络进行互联,进一步保证数据可用性。

Consul角色

  • client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。
  • server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯。 每个数据中心的 server 数量推荐为 3 个或是 5 个。

Consul安装

  • Windows & Linus 安装
https://developer.hashicorp.com/consul/downloads
  • Docker 安装方式
docker pull consul
#单节点方式
docker run -d --name myConsol -p 8500:8500 --network my_consol consul  agent -server -bootstrap -ui -node=consul_node1 -client='0.0.0.0'

启动成功后可以通过  localhost:8500   访问Consul的web管理界面

Go实现Api操作(演示代码)

安装gin和consol依赖

go get github.com/gin-gonic/gin
go get github.com/hashicorp/consul/api
func main(){
    r := gin.Default()
    utils.InitConf()
    v := utils.GetViper()
    bindPort := v.GetString("server.port")
   
    r.GET("/check", func(ctx *gin.Context) {
       ctx.JSON(http.StatusOK, gin.H{
          "message": "ok",
       })
    })
   
    go http.ListenAndServe(":" + bindPort, r)
    consul.ConsulRegister()
   
    //consul.DeRegister()
    //consul.FindService()
    //consul.CheckHeath()
    //consul.KvTest()
   
    select {}
}
import (
   "fmt"
   consulApi "github.com/hashicorp/consul/api"
   "github.com/spf13/viper"
   "log"
   "net"
)

const (
   serverId = "server_123"
)

var client *consulApi.Client
var host string
var post string
var v *viper.Viper

func init() {
   v = utils.GetViper()
   host = v.GetString("consul.host")
   post = v.GetString("consul.port")
   getClient()
}

//服务注册
func ConsulRegister() {
   registration := &consulApi.AgentServiceRegistration{}
   registration.Address = v.GetString("server.host")
   registration.ID = serverId
   registration.Port = v.GetInt("server.port")
   registration.Name = "go-consul-test-server"
   registration.Tags = []string{"tag01", "tag02"}

   check := &consulApi.AgentServiceCheck{}
   check.HTTP = fmt.Sprintf("http://%s:%d/check", registration.Address, registration.Port)
   check.CheckID = serverId
   check.Timeout = "5s"
   check.Interval = "5s"
   check.DeregisterCriticalServiceAfter = "30s"
   registration.Check = check

   err := client.Agent().ServiceRegister(registration)
   if err != nil {
      fmt.Println("ConsulRegister:", err)
   }
}

//服务注销
func DeRegister() {
   client.Agent().ServiceDeregister(serverId)
}

//发现服务
func FindService() {
   services, _ := client.Agent().Services()

   for _, value := range services {
      fmt.Println("Address:", value.Address)
      fmt.Println("Port:", value.Port)
      fmt.Println("ServerId:", value.ID)
   }

   fmt.Println("=========================")

   service, _, err := client.Agent().Service(serverId, nil)
 
   if err != nil {
      fmt.Println("error:", err)
      return
   }
   fmt.Println("Address:", service.Address)
   fmt.Println("Port:", service.Port)
   fmt.Println("Id:", service.ID)
}

//健康检查
func CheckHeath() {
   id, info, err := client.Agent().AgentHealthServiceByID(serverId)

   fmt.Println("err:", err)
   fmt.Printf("info:%v\n", info)
   fmt.Println("id:", id)
}

func KvTest() {
   key := "key_test"
   value := "value_test"
   put, err := client.KV().Put(&consulApi.KVPair{Key: key, Flags: 0, Value: []byte(value)}, nil)
   if err != nil {
    fmt.Println(err)
    return
   }
   fmt.Println("put:", put)
   fmt.Println("=================")

   data, meta, err := client.KV().Get(key, nil)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Printf("data:%#v\n", data)
   fmt.Printf("meta:%#v\n", meta)
   fmt.Println("value:", string(get.Value))

   // KV list
   /*datas, _, _ := client.KV().List("key_", nil)
   for _, value := range datas {
      fmt.Println("val:", string(value.Value))
   }
   keys, _, _ := client.KV().Keys("key_", "", nil)
   fmt.Println("key:", keys)*/
}

func getClient() {
   var err error
   config := consulApi.DefaultConfig()
   config.Address = host + ":" + post
   client, err = consulApi.NewClient(config)
   if err != nil {
      panic(err)
   }
}