注册中心:Consul原理分析

Consul

Consul是一个高可用的分布式服务注册中心,由HashiCorp公司推出,Golang实现的开源共享的服务工具。Consul在分布式服务注册与发现方面有自己的特色,解决方案更加“一站式”,不再需要依赖其他工具。

    1、通过HTTP接口和DNS协议调用API存储键值对,使服务注册和服务发现更容易; 2、支持健康检查,可以快速的告警在集群中的操作 3、支持key/value存储动态配置 4、支持任意数量的区域

Consul 中的概念

Consul安装

mac

brew tap hashicorp/tap
brew install hashicorp/tap/consul
    run
consul agent -server -ui -client 0.0.0.0 -bootstrap-expect=1 -data-dir=/Users/yichuan.deng/soft/consul/data -node=consul-01 -advertise=127.0.0.1 -datacenter SH-TMP -bind=0.0.0.0 -client=0.0.0.0 -log-file=/Users/yichuan.deng/soft/consul/consul.log

Go使用Consul

服务注册

package main

import (
   "fmt"
   "net/http"

   consulAPI "github.com/hashicorp/consul/api"
)

const (
   localIp   = "127.0.0.1"
   localPort = 81
)

func consulRegister() {
          
   
   // 创建连接consul服务配置
   config := consulAPI.DefaultConfig()
   config.Address = "0.0.0.0:8500"
   client, err := consulAPI.NewClient(config)
   if err != nil {
          
   
      fmt.Println("consul client error : ", err)
   }

   // 创建注册到consul的服务到
   registration := new(consulAPI.AgentServiceRegistration)
   registration.ID = "996"
   registration.Name = "service996"
   registration.Port = localPort
   registration.Tags = []string{
          
   "testService"}
   registration.Address = localIp

   // 增加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)
}

func Handler(w http.ResponseWriter, r *http.Request) {
          
   
   w.Write([]byte("health"))
   fmt.Println("health")
}

func main() {
          
   
   consulRegister()
   //定义一个http接口
   http.HandleFunc("/", Handler)
   err := http.ListenAndServe("0.0.0.0:81", nil)
   if err != nil {
          
   
      fmt.Println("error: ", err.Error())
   }
}

可以看到,我们的HTTP服务一直被调用。在consul上也可以看到

服务发现

可以看到,我们在sleep 一分钟后,我们把service 退出之后,健康的service的列表就为空:[] 了。

package main

import (
   "fmt"
   "time"

   consulAPI "github.com/hashicorp/consul/api"
)

const (
   consulAgentAddress = "0.0.0.0:8500"
)

// ConsulFindServer 从consul中发现服务
func ConsulFindServer() {
   // 创建连接consul服务配置
   config := consulAPI.DefaultConfig()
   config.Address = consulAgentAddress
   client, err := consulAPI.NewClient(config)
   if err != nil {
      fmt.Println("consul client error : ", err)
      return
   }

   // 获取指定service
   service, _, err := client.Agent().Service("996", nil)
   if err != nil {
      return
   }
   fmt.Println(service.Address)
   fmt.Println(service.Port)

   time.Sleep(60 * time.Second)
   // 只获取健康的service
   serviceHealthy, _, err := client.Health().Service("service337", "", true, nil)
   if err != nil {
      return
   }
   fmt.Println(serviceHealthy)
}

func main() {
   ConsulFindServer()
}

服务注册与发现

consul client(客户端)使用HTTP或DNS的方式将服务注册到consul server(服务端)注册中心中。服务请求方通过consul server发现他所依赖的服务。

健康检测

consul client提供对应用程序健康检查机制,并将健康检查状态上报给consul server集群,用来监控集群节点的运行状况,并及时下线不健康的节点。

经验分享 程序员 微信小程序 职场和发展