Consul、Etcd、Zookeeper、Nacos 在服务注册与发现中的实现示例

Consul、Etcd、Zookeeper、Nacos 在服务注册与发现中的实现示例

经验文章nimo972025-03-18 22:36:0810A+A-

以下是 Consul、Etcd、Zookeeper、Nacos 在服务注册与发现中的实现示例,结合其核心特性、代码演示及对比分析。


一、Consul

特点:

  • 支持服务发现、健康检查、KV 存储、多数据中心。
  • 基于 HTTP/DNS 接口,提供长轮询和 Watch 机制。

服务注册:

# 通过 HTTP API 注册服务
curl -X PUT \
  http://localhost:8500/v1/agent/service/register \
  -H 'Content-Type: application/json' \
  -d '{
    "ID": "user-service-1",
    "Name": "user-service",
    "Address": "10.0.0.1",
    "Port": 8080,
    "Check": {
      "HTTP": "http://10.0.0.1:8080/health",
      "Interval": "10s"
    }
  }'

服务发现:

# 查询健康服务列表
curl http://localhost:8500/v1/health/service/user-service?passing

Go 客户端示例:

package main

import (
    "fmt"
    "github.com/hashicorp/consul/api"
)

func main() {
    // 连接 Consul
    config := api.DefaultConfig()
    config.Address = "localhost:8500"
    client, _ := api.NewClient(config)

    // 注册服务
    registration := &api.AgentServiceRegistration{
        ID:   "user-service-1",
        Name: "user-service",
        Port: 8080,
        Check: &api.AgentServiceCheck{
            HTTP:     "http://localhost:8080/health",
            Interval: "10s",
        },
    }
    client.Agent().ServiceRegister(registration)

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

二、Etcd

特点:

  • 分布式键值存储,强一致性,基于 gRPC 协议。
  • 常用于 Kubernetes 底层服务发现。

服务注册(使用 etcd3 API):

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    "time"
)

func main() {
    // 连接 Etcd
    cli, _ := clientv3.New(clientv3.Config{
        Endpoints:   []string{"localhost:2379"},
        DialTimeout: 5 * time.Second,
    })
    defer cli.Close()

    // 注册服务(租约机制)
    lease, _ := cli.Grant(context.TODO(), 10) // 10秒租约
    _, _ = cli.Put(context.TODO(), "/services/user-service/10.0.0.1:8080", "", clientv3.WithLease(lease.ID))

    // 自动续约保持服务在线
    keepAlive, _ := cli.KeepAlive(context.TODO(), lease.ID)
    go func() {
        for range keepAlive {
            // 续约成功
        }
    }()

    // 服务发现
    resp, _ := cli.Get(context.TODO(), "/services/user-service/", clientv3.WithPrefix())
    for _, kv := range resp.Kvs {
        fmt.Printf("Service: %s\n", kv.Key)
    }
}

三、Zookeeper

特点:

  • 基于 ZAB 协议的分布式协调服务,提供临时节点(Ephemeral Nodes)和 Watcher 机制。

服务注册(使用 Apache Curator 框架):

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;

public class ZkServiceRegistry {
    public static void main(String[] args) throws Exception {
        // 连接 Zookeeper
        CuratorFramework client = CuratorFrameworkFactory.newClient(
            "localhost:2181",
            new RetryNTimes(3, 1000)
        );
        client.start();

        // 注册服务(临时节点)
        String servicePath = "/services/user-service";
        String instancePath = client.create()
            .creatingParentsIfNeeded()
            .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
            .forPath(servicePath + "/instance", "10.0.0.1:8080".getBytes());

        // 服务发现(监听节点变化)
        List instances = client.getChildren()
            .usingWatcher((CuratorWatcher) event -> {
                System.out.println("Services changed: " + event.getPath());
            })
            .forPath(servicePath);

        System.out.println("Available instances: " + instances);
    }
}

四、Nacos

特点:

  • 动态服务发现、配置管理、易于与 Spring Cloud 和 Kubernetes 集成。

服务注册(使用 Java SDK):

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;

public class NacosExample {
    public static void main(String[] args) throws Exception {
        // 连接 Nacos
        NamingService naming = NacosFactory.createNamingService("localhost:8848");

        // 注册服务
        Instance instance = new Instance();
        instance.setIp("10.0.0.1");
        instance.setPort(8080);
        instance.setServiceName("user-service");
        naming.registerInstance("user-service", instance);

        // 服务发现
        List instances = naming.selectInstances("user-service", true);
        System.out.println("Available instances: " + instances);
    }
}

HTTP API:

# 注册服务
curl -X POST http://localhost:8848/nacos/v1/ns/instance?serviceName=user-service&ip=10.0.0.1&port=8080

# 发现服务
curl http://localhost:8848/nacos/v1/ns/instance/list?serviceName=user-service

五、对比与选型建议

特性

Consul

Etcd

Zookeeper

Nacos

一致性协议

Raft

Raft

ZAB

Raft/Distro

健康检查

内置多种检查方式

无(需自行实现)

无(需自行实现)

内置健康检查

配置管理

支持

支持(KV 存储)

支持(ZK 节点)

支持

多数据中心

原生支持

不支持

不支持

支持

易用性

中等

中等

复杂

高(中文文档友好)

适用场景

多数据中心、大规模微服务

Kubernetes 生态

传统分布式系统

Spring Cloud/云原生

选型建议:

  1. Kubernetes 环境:优先选择 Etcd(已默认集成)。
  2. 多数据中心需求:选择 ConsulNacos
  3. Spring Cloud 集成Nacos(无缝兼容)或 Consul
  4. 简单轻量级场景Nacos(功能全面,学习成本低)。
  5. 传统分布式系统Zookeeper(成熟但配置复杂)。

六、快速启动命令

Consul:

docker run -d --name=consul -p 8500:8500 consul agent -server -bootstrap -ui -client=0.0.0.0

Etcd:

docker run -d --name=etcd -p 2379:2379 quay.io/coreos/etcd:v3.5.0 etcd --advertise-client-urls=http://0.0.0.0:2379 --listen-client-urls=http://0.0.0.0:2379

Zookeeper:

docker run -d --name=zookeeper -p 2181:2181 zookeeper:3.8

Nacos:

docker run -d --name=nacos -p 8848:8848 nacos/nacos-server:v2.1.0

通过以上示例和对比,可根据具体需求选择最适合的服务注册与发现工具。

点击这里复制本文地址 以上内容由nimo97整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

尼墨宝库 © All Rights Reserved.  蜀ICP备2024111239号-7