美文网首页技术文程序员
5分钟了解[Apache]Curator Service Dis

5分钟了解[Apache]Curator Service Dis

作者: chesser | 来源:发表于2016-07-13 22:33 被阅读896次

    Curator Service Discovery要解决什么问题?

    在SOA/分布式的系统中, 大量的services被发布, 运行期诸多的service相互依赖, 而又不停的升级, 上线, 下线, 为了对它们的优雅的管理, Apache的Curator Service Discovery提供了如下机制:

    • service的注册
    • 定位给定service的一个可用实例
    • service的变更通知

    几个概念

    ServiceInstance

    一个service实例.由name, id, address, port/ssl port, payload(可选)构成, 在Zookeeper中的数据组织结构如下:

    base path
           |_______ service A name
                        |__________ instance 1 id --> (serialized ServiceInstance)
                        |__________ instance 2 id --> (serialized ServiceInstance)
                        |__________ ...
           |_______ service B name
                        |__________ instance 1 id --> (serialized ServiceInstance)
                        |__________ instance 2 id --> (serialized ServiceInstance)
                        |__________ ...
           |_______ ...
    

    定义一个实例:

        ServiceInstance<InstanceDetails> service = ServiceInstance.<InstanceDetails>builder()
            .name(serviceName)
            .address(getInnerHostIp())
            .port(port)
            .id(id)
            .serviceType(ServiceType.DYNAMIC)
            .payload(new InstanceDetails(id)).build();
    

    ServiceProvider

    它封装和提供了依据策略来发现service. 所谓的策略(strategy), 就是从给定service的可用instance中怎么选出一个来的策略. 这些策略有:

    • random
    • round robin
    • sticky

    ServiceDiscovery

    它用来分配ServiceProvider; 基本上是我们打交道最多的类之一, 几乎所有对instance的操作都是通过它来实现. 参考如下代码.

    ServiceDiscovery<String> discovery = ServiceDiscoveryBuilder.builder(String.class).basePath("/test").client(client).basePath(basePath).build();
    

    关于builder()和payload

    如上builder()的参数定义了payloadClass, 也就是上面数据结构图里的(serialized ServiceInstance)中的内容.
    我们也可以自定义一个复杂的class用来承载更多的信息; 比如 MoreDetails.class, 不过需要告诉系统, 怎么才能把我们自定义的类"变成"Zookeeper里的payload字符串, 方法就是提供serializer:

    JsonInstanceSerializer<MoreDetails> serializer = new JsonInstanceSerializer<MoreDetails>(MoreDetails.class);
    
    ServiceDiscovery<String> discovery = ServiceDiscoveryBuilder.builder(String.class).basePath("/test").client(client).basePath(basePath).serializer(serializer).build();
    

    如上是通过json的序列化来完成payload的, 如果有进一步的需求, 比如class到json的自定义映射, 用简单的jackson的标注就可以实现.

    实操

    //curator client
    CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
    closeables.add(client);
    client.start();
    
    ServiceInstance<String> instance = ServiceInstance.<String>builder().payload("thing").name("test").port(10064).build();
    ServiceDiscovery<String> discovery = ServiceDiscoveryBuilder.builder(String.class).basePath("/test").client(client).thisInstance(instance).build();
    closeables.add(discovery);
    discovery.start();
    
    Assert.assertEquals(discovery.queryForNames(), Collections.singletonList("test"));
    
    

    CRUD:

    serviceDiscovery.start();
    
    serviceDiscovery.registerService(service);
    
    serviceDiscovery.unregisterService(service);
    
    serviceDiscovery.updateService(service);
    
    serviceDiscovery.queryForInstances(serviceName);
    
    

    相关文章

      网友评论

        本文标题:5分钟了解[Apache]Curator Service Dis

        本文链接:https://www.haomeiwen.com/subject/yskejttx.html