惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
D
Docker
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
A
About on SuperTechFans
博客园 - 【当耐特】
U
Unit 42
H
Help Net Security
博客园 - 三生石上(FineUI控件)
V2EX - 技术
V2EX - 技术
T
Tor Project blog
博客园 - 叶小钗
G
Google Developers Blog
S
Securelist
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threat Research - Cisco Blogs
aimingoo的专栏
aimingoo的专栏
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
V
Vulnerabilities – Threatpost
P
Palo Alto Networks Blog
T
The Exploit Database - CXSecurity.com
The Register - Security
The Register - Security
Recorded Future
Recorded Future
NISL@THU
NISL@THU
量子位
L
LangChain Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CERT Recently Published Vulnerability Notes
The Hacker News
The Hacker News
D
DataBreaches.Net
小众软件
小众软件
罗磊的独立博客
Forbes - Security
Forbes - Security
The Last Watchdog
The Last Watchdog
Jina AI
Jina AI
I
InfoQ
S
Schneier on Security
Recent Announcements
Recent Announcements
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
Secure Thoughts

博客园 - 干炸小黄鱼

timex 处理时间戳 gorm-gen go 雪花算法 golang每日一库--协程池库ants golang每日一库--json解析库gjson python高级编程-asyncio python高级编程-condition python高级编程-event python装饰器-自动重试 EAP系统 go实现实现 SECS/GEM 协议 设备通信协议 SECS go项目使用Jenkins进行CICD go操作ES mongo db聚合查询 go如何使用mongodb Apache ShardingSphere paxos and raft (分布式一致性算法) go使用zookeeper分布式锁以及和redis差异 go使用 seata 示例 Alibaba 分布式事务 Seata go中使用saga go中使用TCC示例 分布式事务TCC 熔断器 Hystrix OR Sentinel k8s下部署consul and etcd 【力扣hot100】双指针-盛水最多的容器 【力扣hot100】滑动窗口-最小覆盖子串 shell脚本合集 分布式id生成器 springboot通用CURD Python PB级检索系统架构设计 rancher 在三台机器搭建k8s集群 python ssh clinet 数据库排序Null值字段靠后/靠前 常规web项目 docker-compose 例子 手搓一个验证码 使用itertools 中的groupby 对字典数组进行分组后排序 使用开源库 geoip2 获取某ip的经纬度地理信息 python中 apscheduler.schedulers.blocking.BlockingScheduler 定时执行任务 简单的python web项目的docker-compose.yml 示例 python和sliver交互 golang sliver二次开发自定义命令(格式乱后面再调) pydantic做参数校验 基于rancher部署k8s 地理位置相关基础数据 flask migrate时报错 Can't locate revision identified by '3d80e4c025df'
Consul OR Etcd
干炸小黄鱼 · 2026-04-20 · via 博客园 - 干炸小黄鱼

在 Go 微服务生态中,ConsulEtcd 是最主流的两个服务注册与发现组件。虽然它们的功能有重叠,但设计理念和适用场景有所不同。

简单来说:

  • Consul:功能大而全,开箱即用,适合以应用为中心的微服务治理,特别是多语言混合环境。
  • Etcd:专注、高性能、强一致性,适合以基础设施为中心的场景,尤其是 Kubernetes 生态或 Go 原生深度定制。

下面我将详细拆解它们的场景和具体用法。


🏛️ Consul:功能丰富的服务治理中心

Consul 是 HashiCorp 推出的工具,它不仅是一个注册中心,还提供了健康检查、KV 存储、多数据中心支持等完整功能。

1. 适用场景

  • 开箱即用的服务发现:你希望快速搭建一个带有健康检查和 Web UI 的注册中心,不想自己写太多底层代码。
  • 多语言混合架构:如果你的系统中有 Java (Spring Cloud)、Node.js、Python 等服务,Consul 提供了标准的 HTTP API 和 DNS 接口,几乎所有语言都有成熟的客户端库,集成非常方便。
  • 配置中心:利用其 KV 存储功能,可以简单地实现动态配置管理(如功能开关、数据库连接串)。
  • 多数据中心:Consul 原生支持多数据中心互联,适合跨机房或跨地域部署的微服务架构。

2. 在 Go 中的用法

在 Go 中使用 Consul 通常有两种方式:直接使用官方 API集成到微服务框架(如 go-micro)

方式一:直接使用官方 API (hashicorp/consul/api)
这种方式最灵活,你可以完全控制注册、心跳和发现的逻辑。

  • 服务注册与心跳

    import (
        consulapi "github.com/hashicorp/consul/api"
    )
    
    // 1. 创建客户端
    config := consulapi.DefaultConfig()
    config.Address = "127.0.0.1:8500"
    client, _ := consulapi.NewClient(config)
    
    // 2. 定义服务注册信息
    registration := &consulapi.AgentServiceRegistration{
        ID:      "user-service-1", // 唯一ID
        Name:    "user-service",   // 服务名
        Address: "192.168.1.10",
        Port:    8080,
        // 3. 配置健康检查 (关键)
        Check: &consulapi.AgentServiceCheck{
            HTTP:     "http://192.168.1.10:8080/health", // 健康检查接口
            Interval: "10s",                             // 检查间隔
            Timeout:  "5s",                              // 超时时间
            // 连续失败30秒后自动注销服务
            DeregisterCriticalServiceAfter: "30s",      
        },
    }
    
    // 4. 注册服务
    client.Agent().ServiceRegister(registration)
    
    // 5. 优雅注销 (在 defer 或信号处理中)
    // client.Agent().ServiceDeregister("user-service-1")
    
  • 服务发现

    // 查询健康的服务实例
    services, _, _ := client.Health().Service("user-service", "", true, nil)
    for _, s := range services {
        fmt.Printf("发现实例: %s:%d\n", s.Service.Address, s.Service.Port)
    }
    

方式二:集成 go-micro 框架
如果你使用 go-micro 框架,Consul 可以作为插件直接注入,无需手写注册逻辑。

import (
    "go-micro.dev/v5"
    "go-micro.dev/v5/registry/consul"
)

func main() {
    // 创建 Consul 注册器
    cr := consul.NewRegistry()

    service := micro.NewService(
        micro.Name("user.service"),
        micro.Registry(cr), // 注入注册器
    )
    
    service.Init()
    service.Run()
}

🗄️ Etcd:云原生时代的强一致性存储

Etcd 是 CoreOS(现属于 RedHat)开发的分布式键值存储,是 Kubernetes 的“大脑”。它基于 Raft 协议,保证强一致性。

1. 适用场景

  • Kubernetes 生态:如果你的微服务运行在 K8s 上,使用 Etcd 作为注册中心可以与 K8s 的基础设施无缝融合,减少运维组件的复杂度。
  • 追求强一致性:Etcd 基于 Raft 协议,保证数据的强一致性(CP 系统)。对于对数据一致性要求极高的场景(如配置管理、Leader 选举),Etcd 是首选。
  • Go 语言深度定制:Etcd 本身是用 Go 写的,Go 客户端库 (go.etcd.io/etcd/client/v3) 非常成熟且高效。
  • 高性能需求:Etcd 的读写性能极高,特别是在高并发读取场景下。

2. 在 Go 中的用法

Etcd 的模型是基于 Key-Value 的,因此“服务注册”本质上是把服务信息(IP、端口)序列化为 JSON,存入一个 Key 中。

核心机制:租约 (Lease) 与 心跳
Etcd 不像 Consul 那样有内置的 HTTP 健康检查,它依赖 TTL (Time To Live)Lease 机制来保证服务存活。

  • 服务注册(带租约)

    import (
        "context"
        "go.etcd.io/etcd/client/v3"
    )
    
    // 1. 创建客户端
    cli, _ := clientv3.New(clientv3.Config{
        Endpoints:   []string{"127.0.0.1:2379"},
        DialTimeout: 5 * time.Second,
    })
    
    // 2. 创建租约 (例如 5秒)
    // 这意味着如果 5秒内不续约,Key 就会自动过期删除
    leaseResp, _ := cli.Grant(context.Background(), 5)
    
    // 3. 服务信息序列化
    serviceInfo := `{"host":"192.168.1.10","port":8080}`
    key := "/services/user-service/192.168.1.10:8080"
    
    // 4. 写入数据并绑定租约
    _, err := cli.Put(context.Background(), key, serviceInfo, clientv3.WithLease(leaseResp.ID))
    
    // 5. 开启心跳协程 (KeepAlive)
    // 客户端需要定期发送心跳来维持租约不过期
    go func() {
        for {
            cli.KeepAlive(context.Background(), leaseResp.ID)
            time.Sleep(2 * time.Second) // 每2秒续约一次
        }
    }()
    
  • 服务发现(监听 Watch)
    Etcd 的强大之处在于 Watch 机制。客户端不需要轮询,而是监听 Key 的变化。

    // 1. 监听 /services/user-service/ 前缀下的所有变化
    watchChan := cli.Watch(context.Background(), "/services/user-service/", clientv3.WithPrefix())
    
    // 2. 处理事件
    for watchResp := range watchChan {
        for _, event := range watchResp.Events {
            switch event.Type {
            case mvccpb.PUT:
                fmt.Println("新服务上线:", string(event.Kv.Value))
            case mvccpb.DELETE:
                fmt.Println("服务下线:", string(event.Kv.Key))
            }
        }
    }
    

📌 总结与对比

特性 Consul Etcd
核心定位 服务发现 + 配置管理 + 健康检查 分布式键值存储 (K8s 标配)
一致性协议 Raft (但在服务发现场景通常追求最终一致性) 强一致性 (Raft)
健康检查 内置 HTTP/TCP/Script 检查,服务端主动探测 依赖客户端 Lease/TTL 心跳,被动过期
数据模型 结构化服务注册信息 简单的 Key-Value
Go 集成难度 低 (官方库完善,框架支持好) 中 (需要自己封装注册/发现逻辑或利用框架)
适用推荐 通用微服务架构,特别是多语言环境,追求功能丰富。 K8s 环境,或追求极致性能和强一致性的 Go 原生架构。

建议:

  • 如果你是刚开始构建微服务,或者团队技术栈比较杂,Consul 是最稳妥、最省心的选择。
  • 如果你深度依赖 Kubernetes,或者想要构建一个类似 Go-Zero / Kratos 这样的高性能原生框架,Etcd 是更底层、更强大的基石。