Zookeeper 用户服务注册与发现的 Java 代码实现

Zookeeper 用户服务注册与发现的 Java 代码实现

下面我将提供一个完整的 Zookeeper 实现服务注册与发现的 Java 代码示例,使用 Apache Curator 框架(Zookeeper 的高级客户端库)。

1. 添加 Maven 依赖

首先,在你的 pom.xml 中添加以下依赖:

<dependencies>
    <!-- Curator Framework -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>5.2.0</version>
    </dependency>
    
    <!-- Curator Recipes -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>5.2.0</version>
    </dependency>
    
    <!-- Zookeeper -->
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.7.0</version>
    </dependency>
</dependencies>

2. 服务注册实现

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.UriSpec;
import org.apache.curator.x.discovery.details.JsonInstanceSerializer;

import java.util.Collection;

public class ServiceRegistry {

    private final ServiceDiscovery<InstanceDetails> serviceDiscovery;
    private final CuratorFramework client;

    public ServiceRegistry(String zookeeperAddress) throws Exception {
        // 创建 Curator 客户端
        client = CuratorFrameworkFactory.newClient(
                zookeeperAddress,
                new ExponentialBackoffRetry(1000, 3)
        );
        client.start();

        // 创建 ServiceDiscovery 实例
        JsonInstanceSerializer<InstanceDetails> serializer = 
            new JsonInstanceSerializer<>(InstanceDetails.class);
        
        serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class)
                .client(client)
                .basePath("/services")
                .serializer(serializer)
                .build();
        
        serviceDiscovery.start();
    }

    public void registerService(String serviceName, String instanceId, String address, int port) throws Exception {
        // 创建服务实例
        ServiceInstance<InstanceDetails> instance = ServiceInstance.<InstanceDetails>builder()
                .name(serviceName)
                .id(instanceId)
                .address(address)
                .port(port)
                .uriSpec(new UriSpec("{scheme}://{address}:{port}"))
                .payload(new InstanceDetails("V1.0"))
                .build();

        // 注册服务
        serviceDiscovery.registerService(instance);
        System.out.println("Service registered: " + instance);
    }

    public Collection<ServiceInstance<InstanceDetails>> queryForInstances(String serviceName) throws Exception {
        return serviceDiscovery.queryForInstances(serviceName);
    }

    public void close() throws Exception {
        serviceDiscovery.close();
        client.close();
    }

    // 服务实例详情类
    public static class InstanceDetails {
        private String version;

        public InstanceDetails() {
        }

        public InstanceDetails(String version) {
            this.version = version;
        }

        public String getVersion() {
            return version;
        }

        public void setVersion(String version) {
            this.version = version;
        }
    }
}

3. 服务发现实现

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.details.JsonInstanceSerializer;

import java.util.Collection;

public class ServiceDiscoveryClient {

    private final ServiceDiscovery<ServiceRegistry.InstanceDetails> serviceDiscovery;
    private final CuratorFramework client;

    public ServiceDiscoveryClient(String zookeeperAddress) throws Exception {
        // 创建 Curator 客户端
        client = CuratorFrameworkFactory.newClient(
                zookeeperAddress,
                new ExponentialBackoffRetry(1000, 3)
        );
        client.start();

        // 创建 ServiceDiscovery 实例
        JsonInstanceSerializer<ServiceRegistry.InstanceDetails> serializer = 
            new JsonInstanceSerializer<>(ServiceRegistry.InstanceDetails.class);
        
        serviceDiscovery = ServiceDiscoveryBuilder.builder(ServiceRegistry.InstanceDetails.class)
                .client(client)
                .basePath("/services")
                .serializer(serializer)
                .build();
        
        serviceDiscovery.start();
    }

    public Collection<ServiceInstance<ServiceRegistry.InstanceDetails>> discoverServices(String serviceName) throws Exception {
        return serviceDiscovery.queryForInstances(serviceName);
    }

    public void close() throws Exception {
        serviceDiscovery.close();
        client.close();
    }
}

4. 使用示例

服务提供者 (注册服务)

public class ServiceProvider {
    public static void main(String[] args) throws Exception {
        String zookeeperAddress = "localhost:2181";
        String serviceName = "user-service";
        String instanceId = "user-service-1";
        String address = "192.168.1.100";
        int port = 8080;

        ServiceRegistry registry = new ServiceRegistry(zookeeperAddress);
        registry.registerService(serviceName, instanceId, address, port);

        // 保持服务运行
        Thread.sleep(Long.MAX_VALUE);
        
        registry.close();
    }
}

服务消费者 (发现服务)

public class ServiceConsumer {
    public static void main(String[] args) throws Exception {
        String zookeeperAddress = "localhost:2181";
        String serviceName = "user-service";

        ServiceDiscoveryClient discoveryClient = new ServiceDiscoveryClient(zookeeperAddress);
        
        while (true) {
            Collection<ServiceInstance<ServiceRegistry.InstanceDetails>> instances = 
                discoveryClient.discoverServices(serviceName);
            
            System.out.println("Discovered " + instances.size() + " instances:");
            for (ServiceInstance<ServiceRegistry.InstanceDetails> instance : instances) {
                System.out.println(" - " + instance.getAddress() + ":" + instance.getPort() + 
                                 " (Version: " + instance.getPayload().getVersion() + ")");
            }
            
            Thread.sleep(5000);
        }
        
        // discoveryClient.close(); // 实际应用中应该关闭
    }
}

5. 高级功能扩展

服务健康检查

import org.apache.curator.framework.recipes.healthcheck.HealthCheck;
import org.apache.curator.framework.recipes.healthcheck.HealthCheckListener;

public class HealthCheckExample {
    public static void addHealthCheck(CuratorFramework client, String servicePath) {
        HealthCheck healthCheck = new HealthCheck(client, servicePath);
        healthCheck.addListener(new HealthCheckListener() {
            @Override
            public void isHealthy(boolean healthy) {
                if (!healthy) {
                    System.out.println("Service is unhealthy: " + servicePath);
                    // 可以在这里触发服务重启或其他恢复操作
                }
            }
        });
        healthCheck.start();
    }
}

负载均衡

import org.apache.curator.x.discovery.ServiceProvider;
import org.apache.curator.x.discovery.strategies.RoundRobinStrategy;

public class LoadBalancer {
    private ServiceProvider<ServiceRegistry.InstanceDetails> serviceProvider;

    public LoadBalancer(ServiceDiscovery<ServiceRegistry.InstanceDetails> serviceDiscovery, 
                      String serviceName) throws Exception {
        serviceProvider = serviceDiscovery.serviceProviderBuilder()
                .serviceName(serviceName)
                .providerStrategy(new RoundRobinStrategy<>())
                .build();
        
        serviceProvider.start();
    }

    public ServiceInstance<ServiceRegistry.InstanceDetails> getInstance() throws Exception {
        return serviceProvider.getInstance();
    }

    public void close() throws Exception {
        serviceProvider.close();
    }
}

注意事项

  1. 确保 Zookeeper 服务已经启动并运行
  2. 在生产环境中,应该添加适当的异常处理和重试逻辑
  3. 考虑使用连接状态监听器来处理连接丢失和重新连接的情况
  4. 服务注册后应该定期检查健康状态
  5. 服务下线时应该正确注销服务实例

以上代码提供了一个完整的 Zookeeper 服务注册与发现实现,你可以根据实际需求进行调整和扩展。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值