12-注册中心-consul
作者:互联网
一 注册中心
1.1 服务注册与发现
在使用微服务后,调用都变成了服务间的调用。
服务间调用需要知道IP、端口等信息。
在没有微服务之前,我们的调用信息一般都是写死在调用方的配置文件里(有的公司把这些信息写到数据库等公共的地方,以方便维护)。
由于业务的复杂,每个服务可能依赖N个其他服务,如果某个服务的IP,端口等信息发生变更,那么所有依赖该服务的服务的配置文件都要去修改,这样显然太麻烦了。
有些服务为了负载是有个多个实例的,而且可能是随时会调整实例的数量。如果每次调整实例数量都要去修改其他服务的配置并重启那太麻烦了。
为了解决这个问题,就有了注册中心
假设我们有服务A需要调用服务B,并且有服务注册发现组件R。整个大致流程将变成3步:
- 服务B启动时,向注册中心注册资金
- 服务A从从注册中心拉取服务B的信息
- 服务A调用服务B
有了服务注册发现组件之后,当修改A服务信息的时候再也不用去修改其他相关服务了
1.2 分布式一致性算法
一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的
一致性协议算法主要有:Paxos、Raft、ZAB、Gossip
具体参照:https://zhuanlan.zhihu.com/p/130332285
Paxos算法是Leslie Lamport在1990年提出的一种基于消息传递的一致性算法,非常难以理解,基于Paxos协议的数据同步与传统主备方式最大的区别在于:Paxos只需超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失。
Raft是斯坦福大学的Diego Ongaro、John Ousterhout两个人以易理解为目标设计的一致性算法,已经有了十几种语言的Raft算法实现框架,较为出名的有etcd,Google的Kubernetes也是用了etcd作为他的服务发现框架。
Raft是Paxos的简化版,与Paxos相比,Raft强调的是易理解、易实现,Raft和Paxos一样只要保证超过半数的节点正常就能够提供服务。这篇文章 《ETCD教程-2.Raft协议》 详细讲解了Raft原理,非常有意思,感兴趣的同学可以看看。
ZooKeeper Atomic Broadcast (ZAB, ZooKeeper原子消息广播协议)是ZooKeeper实现分布式数据一致性的核心算法,ZAB借鉴Paxos算法,但又不像Paxos算法那样,是一种通用的分布式一致性算法,它是一种特别为ZooKeeper专门设计的支持崩溃恢复的原子广播协议
1.3 注册中心选型
5种常用的注册中心,分别为Zookeeper、Eureka、Nacos、Consul和ETCD
具体参照:https://blog.csdn.net/lml200701158/article/details/123153513
二 Consul
2.1 介绍
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper 等)。
Consul 使用起来也较为简单,使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合
Consul 主要特征
2.2 consul特点
CP模型,使用 Raft 算法来保证强一致性,不保证可用性;
支持服务注册与发现、健康检查、KV Store功能。
支持多数据中心,可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等。
支持安全服务通信,Consul可以为服务生成和分发TLS证书,以建立相互的TLS连接。
支持 http 和 dns 协议接口;
官方提供 web 管理界面
2.3 安装
普通安装
下载地址:https://www.consul.io/downloads
win
//1 下载
//2 加入环境变量
//3 执行
consul agent -dev
mac
//1 下载
//2 加入环境变量
//3 执行
consul agent -dev
docker安装
//1 使用docker下载consul
//同步时间:ntpdate cn.pool.ntp.org
docker pull docker.io/library/consul
//2 修改consul tag
docker tag docker.io/library/consul consul
//3 启动
docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp consul consul agent -dev -client=0.0.0.0
//4 浏览器中访问web页面
// 8500端口:http端口,我们进行服务注册发现使用http端口
// 8600端口:dns端口
//5 dig 命令,通过域名解析地址和端口
//dig命令dns地址为10.0.0.102,
//端口为:8600,
//域名为:service的名字.service.consul ---》自动生成
//查询类型指定为为srv
dig @10.0.0.102 -p 8600 consul.service.consul SRV
三 常用API
3.1 服务注册
参考文档:https://www.consul.io/commands/services/register
// put 请求
// 地址:/v1/agent/service/register
// Service Registration Flags
-name:The name of the service to register-->服务的名字
-id:The ID of the service. This will default to -name if not set--》id不设置与name一致
-tag value - Associate a tag with the service instance. This flag can be specified multiples times.-->服务的标签
-address - The address of the service. If this isn't specified, it will default to the address registered with the local agent.
-port - The port of the service.
使用postman注册演示
// 向http://10.0.0.102:8500/v1/agent/service/register发送put请求
// body体数据为
{
"Name":"lqz",
"ID":"ddd",
"Tags":["lqz","web"],
"Address":"127.0.0.1",
"Port":8080
}
Go 语言注册
package main
import "fmt"
import consulapi "github.com/hashicorp/consul/api"
const (
consulAddress = "10.0.0.102:8500"
)
func RegisterConsul(localIP string, localPort int, name string,id string, tags []string) error {
// 创建连接consul服务配置
config := consulapi.DefaultConfig()
config.Address = consulAddress
client, err := consulapi.NewClient(config)
if err != nil {
fmt.Println("consul client error : ", err)
}
// 创建注册到consul的服务到
registration := new(consulapi.AgentServiceRegistration)
registration.ID = id
registration.Name = name //根据这个名称来找这个服务
registration.Port = localPort
//registration.Tags = []string{"lqz", "web"} //这个就是一个标签,可以根据这个来找这个服务,相当于V1.1这种
registration.Tags = tags //这个就是一个标签,可以根据这个来找这个服务,相当于V1.1这种
registration.Address = localIP
// 增加consul健康检查回调函数
check := new(consulapi.AgentServiceCheck)
check.HTTP = fmt.Sprintf("http://%s:%d/health", 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 {
return err
}
return nil
}
func main() {
// 1 注册
RegisterConsul("192.168.1.1",8080,"lqz_web","lqz_web",[]string{"lqz","web"})
}
3.2 服务删除
参考:https://www.consul.io/commands/services/deregister
使用postman注册演示
// 向 http://10.0.0.102:8500/v1/agent/service/deregister/ddd发送put请求
go代码
func DeleteService() error {
// 创建连接consul服务配置
config := consulapi.DefaultConfig()
config.Address = consulAddress
client, err := consulapi.NewClient(config)
if err != nil {
fmt.Println("consul client error : ", err)
}
err = client.Agent().ServiceDeregister("qqq")
if err != nil {
return err
}
return nil
}
3.3 设置健康检查
参考:https://www.consul.io/api-docs/agent/check#register-check
3.4 获取服务
参考:https://www.consul.io/api-docs/agent/service#sample-request
获取所有
func GetAllService() (map[string]*consulapi.AgentService, error) {
// 创建连接consul服务配置
config := consulapi.DefaultConfig()
config.Address = consulAddress
client, err := consulapi.NewClient(config)
if err != nil {
fmt.Println("consul client error : ", err)
}
res, err := client.Agent().Services()
if err != nil {
return nil, err
}
return res, nil
}
过滤服务
func FilterService() (map[string]*consulapi.AgentService, error) {
// 创建连接consul服务配置
config := consulapi.DefaultConfig()
config.Address = consulAddress
client, err := consulapi.NewClient(config)
if err != nil {
fmt.Println("consul client error : ", err)
}
//res, err := client.Agent().ServicesWithFilter(`Service=="lqz-web03"`)// 按服务名字过滤
res, err := client.Agent().ServicesWithFilter(`Port==8087`) // 按端口过滤
if err != nil {
return nil, err
}
return res, nil
}
3.5 同一个服务注册多次
name一样,id不一样会把name一样的放到一起
标签:12,服务,err,nil,consul,client,注册 来源: https://www.cnblogs.com/liuqingzheng/p/16296785.html