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)
}
}