go使用consul实现服务发现及配置共享实现详解

 更新时间:2022年05月19日 10:16:42   作者:dz45693  
这篇文章主要为大家介绍了go使用consul实现服务发现及配置共享实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

使用consul四大特性

1. 服务发现:利用服务注册,服务发现功能来实现服务治理。

2. 健康检查:利用consul注册的检查检查函数或脚本来判断服务是否健康,若服务不存在则从注册中心移除该服务,减少故障服务请求。

3. k/v数据存储:存储kv数据,可以作为服务配置中心来使用。

4. 多数据中心:可以建立多个consul集群通过inter网络进行互联,进一步保证数据可用性。

通过docker安装consul

docker pull consul:latest
//运行单机
docker run -d --restart=always --name consul -d -p 8500:8500 consul
/*
8500 http 端口,用于 http 接口和 web ui
8300 server rpc 端口,同一数据中心 consul server 之间通过该端口通信
8301 serf lan 端口,同一数据中心 consul client 通过该端口通信
8302 serf wan 端口,不同数据中心 consul server 通过该端口通信
8600 dns 端口,用于服务发现
-bbostrap-expect 2: 集群至少两台服务器,才能选举集群leader
-ui:运行 web 控制台
-bind: 监听网口,0.0.0.0 表示所有网口,如果不指定默认未127.0.0.1,则无法和容器通信
-client : 限制某些网口可以访问
*/
//集群
docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:latest agent -server -bootstrap-expect 2 -ui -bind=0.0.0.0 -client=0.0.0.0
docker run --name consul2 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
docker run --name consul2 -d -p 8502:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2

实现代码

以下代码实现一个服务注册,服务发现,配置共享的功能:

package main
import (
    "net"
    "github.com/gin-gonic/gin"
    "fmt"
    "log"
    "net/http"
    consulapi "github.com/hashicorp/consul/api"
)
const (
    consulAddress = "192.168.100.19:8500"
    serviceId     = "111"
)
func main() {
    r := gin.Default()
    // consul健康检查回调函数
    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "ok",
        })
    })
    go http.ListenAndServe(":8081", r)
    // 注册服务到consul
    ConsulRegister()
    // 从consul中发现服务
    ConsulFindServer()
    ConsulCheckHeath()
    ConsulKVTest()
    // 取消consul注册的服务
    //ConsulDeRegister()
    var str string
    fmt.Scan(&str)
}
// 注册服务到consul
func ConsulRegister() {
    // 创建连接consul服务配置
    config := consulapi.DefaultConfig()
    config.Address = consulAddress
    client, err := consulapi.NewClient(config)
    if err != nil {
        log.Fatal("consul client error : ", err)
    }
    // 创建注册到consul的服务到
    registration := new(consulapi.AgentServiceRegistration)
    registration.ID = serviceId                    // 服务节点的名称
    registration.Name = "go-consul-test"           // 服务名称
    registration.Port = 8081                       // 服务端口
    registration.Tags = []string{"go-consul-test"} // tag,可以为空
    registration.Address = "192.168.3.42"          // 服务 IP 要确保consul可以访问这个ip
    // 增加consul健康检查回调函数
    check := new(consulapi.AgentServiceCheck)
    check.HTTP = fmt.Sprintf("http://%s:%d", registration.Address, registration.Port)
    check.Timeout = "5s"
    check.Interval = "5s"                        // 健康检查间隔
    check.DeregisterCriticalServiceAfter = "30s" // 故障检查失败30s后 consul自动将注册服务删除
    registration.Check = check
    // 注册服务到consul
    err = client.Agent().ServiceRegister(registration)
    if err == nil {
        fmt.Println("ConsulRegister done")
    }
}
// 取消consul注册的服务
func ConsulDeRegister() {
    // 创建连接consul服务配置
    config := consulapi.DefaultConfig()
    config.Address = consulAddress
    client, err := consulapi.NewClient(config)
    if err != nil {
        log.Fatal("consul client error : ", err)
    }
    client.Agent().ServiceDeregister(serviceId)
}
// 从consul中发现服务
func ConsulFindServer() {
    // 创建连接consul服务配置
    config := consulapi.DefaultConfig()
    config.Address = consulAddress
    client, err := consulapi.NewClient(config)
    if err != nil {
        log.Fatal("consul client error : ", err)
    }
    // 获取所有service
    services, _ := client.Agent().Services()
    for _, value := range services {
        fmt.Println("address:", value.Address)
        fmt.Println("port:", value.Port)
    }
    fmt.Println("=================================")
    // 获取指定service
    service, _, err := client.Agent().Service(serviceId, nil)
    if err == nil {
        fmt.Println("address:", service.Address)
        fmt.Println("port:", service.Port)
    }
    if err == nil {
        fmt.Println("ConsulFindServer done")
    }
}
func ConsulCheckHeath() {
    // 创建连接consul服务配置
    config := consulapi.DefaultConfig()
    config.Address = consulAddress
    client, err := consulapi.NewClient(config)
    if err != nil {
        log.Fatal("consul client error : ", err)
    }
    // 健康检查
    a, b, _ := client.Agent().AgentHealthServiceByID(serviceId)
    fmt.Println("val1:", a)
    fmt.Println("val2:", b)
    fmt.Println("ConsulCheckHeath done")
}
func ConsulKVTest() {
    // 创建连接consul服务配置
    config := consulapi.DefaultConfig()
    config.Address = consulAddress
    client, err := consulapi.NewClient(config)
    if err != nil {
        log.Fatal("consul client error : ", err)
    }
    // KV, put值
    values := "test"
    key := "go-consul-test"
    client.KV().Put(&consulapi.KVPair{Key: key, Flags: 0, Value: []byte(values)}, nil)
    // KV get值
    data, _, _ := client.KV().Get(key, nil)
    fmt.Println("data:", string(data.Value))
    // KV list
    datas, _, _ := client.KV().List("go", nil)
    for _, value := range datas {
        fmt.Println("val:", value)
    }
    keys, _, _ := client.KV().Keys("go", "", nil)
    fmt.Println("key:", keys)
    fmt.Println("ConsulKVTest done")
}
func localIP() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        return ""
    }
    for _, address := range addrs {
        if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                return ipnet.IP.String()
            }
        }
    }
    return ""
}

运行结果

以上就是go使用consul实现服务发现及配置共享实现详解的详细内容,更多关于go consul服务发现配置共享的资料请关注脚本之家其它相关文章!

相关文章

  • golang基于Mutex实现可重入锁

    golang基于Mutex实现可重入锁

    锁可重入也就是当前已经获取到锁的goroutine继续调用Lock方法获取锁,Go标准库中提供了sync.Mutex实现了排他锁,但并不是可重入的,所以本文给大家介绍了golang基于Mutex实现可重入锁,文中有详细的代码示例,需要的朋友可以参考下
    2024-03-03
  • go语言中函数的用法示例详解

    go语言中函数的用法示例详解

    Go语言中函数是基本的代码组织单元,用于封装一段代码,使代码结构更清晰、可复用,本文详细讲解了基本函数定义、参数传递、返回值、多返回值、匿名函数、递归和defer语句的使用,感兴趣的朋友一起看看吧
    2024-10-10
  • Go语言生成素数的方法

    Go语言生成素数的方法

    这篇文章主要介绍了Go语言生成素数的方法,实例分析了Go语言生成素数的技巧,需要的朋友可以参考下
    2015-03-03
  • Golang必知必会之Go Mod命令详解

    Golang必知必会之Go Mod命令详解

    go mod可以使项目从GOPATH的强制依赖中独立出来,也就是说你的项目依赖不再需要放在在GOPATH下面了,下面这篇文章主要给大家介绍了关于Golang必知必会之Go Mod命令的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • 基于Golang实现延迟队列(DelayQueue)

    基于Golang实现延迟队列(DelayQueue)

    延迟队列是一种特殊的队列,元素入队时需要指定到期时间(或延迟时间),从队头出队的元素必须是已经到期的。本文将用Golang实现延迟队列,感兴趣的可以了解下
    2022-09-09
  • Go语言等待组sync.WaitGrou的使用示例

    Go语言等待组sync.WaitGrou的使用示例

    本文主要介绍了Go语言等待组sync.WaitGrou的使用示例,sync.WaitGroup只有3个方法,Add(),Done(),Wait(),下面就来具体的介绍一下如何使用,感兴趣的可以了解一下
    2024-08-08
  • Golang map实现原理深入分析

    Golang map实现原理深入分析

    map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用,下面这篇文章主要给大家介绍了关于golang中map使用的几点注意事项,需要的朋友可以参考下
    2023-01-01
  • Beego AutoRouter工作原理解析

    Beego AutoRouter工作原理解析

    这篇文章主要为大家介绍了Beego AutoRouter工作原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Go语言基础函数包的使用学习

    Go语言基础函数包的使用学习

    本文通过一个实现加减乘除运算的小程序来介绍go函数的使用,以及使用函数的注意事项,并引出了对包的了解和使用,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 详解golang中make与new的异同点和用法

    详解golang中make与new的异同点和用法

    这篇文章将给大家介绍了go语言中函数new与make的使用和区别,关于go语言中new和make是内建的两个函数,主要用来创建分配类型内存,文中通过代码示例介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2024-01-01

最新评论