技术文程序员

5分钟了解[Apache]Curator Service Dis

2016-07-13  本文已影响896人  chesser

Curator Service Discovery要解决什么问题?

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

几个概念

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中怎么选出一个来的策略. 这些策略有:

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);

上一篇下一篇

猜你喜欢

热点阅读