[原]Curator服务发现

标签: | 发表时间:2016-02-13 23:50 | 作者:GreatElite
出处:http://blog.csdn.net/greatelite

3.3.1 服务发现

一个服务发现系统提供下面几个机制:

 注册它们有用的服务

 定位一个单一特殊服务的实例

 当一个服务改变时发出通知

3.3.1.1 服务实例

一个服务实例使用类ServiceInstance作为服务实例类。ServiceInstance有一个名称、id、地址、端口或者ssl端口以及可选负载(用户定义)。ServiceInstances序列化并存储到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)
                    |__________ ...
       |_______ ...

3.3.1.2 服务提供者

主要抽象类是ServiceProvider,它提供了命名的服务、提供策略等服务。服务策略有三种: Round Robin, Random 和 Sticky(总是选择相同一个)。

ServiceProvider开始服务类必须提供start()开始方法和完成时调用close()。唯一在ServiceProvider类的方法有下面定义:

  public ServiceInstance<T> getInstance()
                            throws Exception
Return an instance for a single use. IMPORTANT: users should not hold on to the instance
returned. A fresh instance should always be retrieved.
Returns: the instance to use

3.3.1.3 服务发现

为了分配一个ServiceProvider,你必须有一个ServiceDiscovery类。服务发现类是由ServiceDiscoveryBuilder构建的。

3.3.1.4 实例程序

我们创建一个注册服务的简单程序,改程序主要由三个类组成。

 DistributedService: 注册服务类,提供服务的地址,服务内容信息。

 DistributedServer: 分布式服务的服务类,创建服务实例,注册服务。

 DistributedDiscovery:分布式服务发现类,服务类的初始化,添加、删除、呈现服务。

DistributedService类定义:

  import org.codehaus.jackson.map.annotate.JsonRootName;

/**
 * @author: elite_jigang@163.com
 */
@JsonRootName("services")
public class DistributedService {
    private String address ;
    private String info;

    public DistributedService(){
        this("", "");
    }
    public DistributedService(String address, String info){
        this.address = address;
        this.info = info;
    }
    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

DistributedServer类定义:

  import org.apache.curator.framework.CuratorFramework;
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.io.Closeable;
import java.io.IOException;

/**
 * @author: elite_jigang@163.com
 */
public class DistributedServer  implements Closeable {

    private final ServiceDiscovery<DistributedService> serviceDiscovery;
    private final ServiceInstance<DistributedService> thisInstance;

    DistributedServer(CuratorFramework client,
                      String path,
                      String serviceName,
                      String address,
                      String info ) throws Exception {
        // in a real application, you'd have a convention of some kind for the URI layout
        UriSpec uriSpec = new UriSpec("{scheme}://zookeeper.com:{port}");

        thisInstance = ServiceInstance.<DistributedService>builder()
                .name(serviceName)
                .payload(new DistributedService(address, info))
                .port((int) (65535 * Math.random())) // in a real application, you'd use a common port
                .uriSpec(uriSpec)
                .build();

        // if you mark your payload class with @JsonRootName the provided JsonInstanceSerializer will work
        JsonInstanceSerializer<DistributedService> serializer = new
                JsonInstanceSerializer<DistributedService>(DistributedService.class);

        serviceDiscovery = ServiceDiscoveryBuilder.builder(DistributedService.class)
                .client(client)
                .basePath(path)
                .serializer(serializer)
                .thisInstance(thisInstance)
                .build();
    }

    public ServiceInstance<DistributedService> getThisInstance() {
        return thisInstance;
    }

    public void start() throws Exception {
        serviceDiscovery.start();
    }


    @Override
    public void close() throws IOException {
        serviceDiscovery.close();
    }
}

DistributedDiscover类定义:

  import com.google.common.collect.Lists;
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 util.ZooKeeperConf;

import java.util.Collection;
import java.util.List;

/**
 * @author elite_jigang@163.com
 */
public class DistributedDiscovery {

    private List<DistributedServer> servers = Lists.newArrayList();
    private static final String PATH = "/discovery/distributed_services";
    private CuratorFramework client = null;
    private ServiceDiscovery<DistributedService> serviceDiscovery = null;

    public DistributedDiscovery(){
        init();
    }
    public void init(){
        client = CuratorFrameworkFactory.newClient(ZooKeeperConf.CLUSTER_NODES,
                new ExponentialBackoffRetry(1000, 3));
        client.start();

        JsonInstanceSerializer<DistributedService> serializer = new
                JsonInstanceSerializer<DistributedService>(DistributedService.class);
        serviceDiscovery = ServiceDiscoveryBuilder.builder(DistributedService.class)
                .client(client)
                .basePath(PATH)
                .serializer(serializer)
                .build();
        try {
            serviceDiscovery.start();
        } catch (Exception e) {
            System.out.println("serviceServiceDiscovery.start() with an exception." +
                    e.getMessage());
            e.printStackTrace();
        }
    }

    public void addService(String serviceName,
                           String address,
                           String info) throws Exception {
        DistributedServer server = new DistributedServer(client, PATH, serviceName,address,  info);
        servers.add(server);
        server.start();

        System.out.println(serviceName + " added");
    }

    public void listServices() throws Exception {
        Collection<String> serviceNames = serviceDiscovery.queryForNames();
        System.out.println(serviceNames.size() + " type(s)");
        for (String serviceName : serviceNames) {
            Collection<ServiceInstance<DistributedService>> instances = serviceDiscovery.queryForInstances(serviceName);
            System.out.println(serviceName);
            for(ServiceInstance<DistributedService> instance: instances){
                outputInstance(instance);
            }
        }
    }
    private static void outputInstance(ServiceInstance<DistributedService> instance) {
        System.out.println("\t address: " + instance.getPayload().getAddress()+ ", info: " +
                instance.getPayload().getInfo()+ ": " + instance.buildUriSpec());
    }
    public List<DistributedServer> getServers() {
        return servers;
    }
}

下面是测试类ServicesMain

  import java.lang.management.ManagementFactory;
import java.util.concurrent.Callable;

/**
 * @author elite_jigang@163.com
 */
public class ServicesMain {

    public static void main(String[] args) throws Exception {
        DistributedDiscovery dd = new DistributedDiscovery();

        String name = ManagementFactory.getRuntimeMXBean().getName();
        System.out.printf("getRuntimeMXBean mame: %s", name);
        int index = name.indexOf('@');
        // pid as the service name .
        dd.addService(name.substring(0, index), "192.168.11.2:8089", "cluster node 1");


        //
        dd.addService(name, "192.168.11.3:8089", "cluster node 2");
        dd.listServices();
//        Callable<Boolean > callable = new Callable<Boolean>(){
//            @Override
//            public Boolean call() throws Exception{
//                System.out.println();
//                boolean isStop = true;
//                while(isStop){
//                    //wait 10 seconds
//                    Thread.sleep(10000);
//                    isStop = false;
//                }
//                return true;
//            }
//        };
//        callable.call();
        Thread.currentThread().sleep(10000);
        dd.listServices();
    }
}
  多次执行上面的代码,你可以看到第一次执行时,会打印出所有的注册服务。一旦有的注册服务消失,发现到的服务也会减少。
  getRuntimeMXBean mame: 8040@JOHNLAU--localhost: 172.24.219.99
8040 added
--localhost: 172.24.219.99
8040@JOHNLAU added
10 type(s)
test-b
test-a
2620
     address: 192.168.11.2:8089, info: cluster node 1: http://zookeeper.com:42118
8040@JOHNLAU
     address: 192.168.11.3:8089, info: cluster node 2: http://zookeeper.com:17009
7896
10004@JOHNLAU
2620@JOHNLAU
     address: 192.168.11.3:8089, info: cluster node 2: http://zookeeper.com:58955
10004
7896@JOHNLAU
8040
     address: 192.168.11.2:8089, info: cluster node 1: http://zookeeper.com:53458
10 type(s)
test-b
test-a
2620
     address: 192.168.11.2:8089, info: cluster node 1: http://zookeeper.com:42118
8040@JOHNLAU
     address: 192.168.11.3:8089, info: cluster node 2: http://zookeeper.com:17009
7896
10004@JOHNLAU
2620@JOHNLAU
     address: 192.168.11.3:8089, info: cluster node 2: http://zookeeper.com:58955
10004
7896@JOHNLAU
8040
     address: 192.168.11.2:8089, info: cluster node 1: http://zookeeper.com:53458
Disconnected from the target VM, address: '127.0.0.1:58347', transport: 'socket'
作者:GreatElite 发表于2016/2/13 23:50:01 原文链接
阅读:3 评论:0 查看评论

相关 [curator 服务 发现] 推荐:

[原]Curator服务发现

- - 升华思想 技术高深
一个服务发现系统提供下面几个机制:.  注册它们有用的服务.  定位一个单一特殊服务的实例.  当一个服务改变时发出通知. 3.3.1.1 服务实例. 一个服务实例使用类ServiceInstance作为服务实例类. ServiceInstance有一个名称、id、地址、端口或者ssl端口以及可选负载(用户定义).

Apache Curator入门实战

- - CSDN博客综合推荐文章
Apache Curator入门实战. Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. 1.Zookeeper安装部署. Zookeeper的部署很简单,如果已经有Java运行环境的话,下载tarball解压后即可运行.

zookeeper客户端curator使用手记

- - 五四陈科学院-坚信科学,分享技术
以下内容由 [五四陈科学院]提供. curator是Netflix公司开源的一个Zookeeper client library,用于简化zookeeper客户端编程,包含一下几个模块:. curator-client - zookeeper client封装,用于取代原生的zookeeper客户端,提供一些非常有用的客户端特性.

Zookeeper开源客户端框架Curator简介

- - 编程语言 - ITeye博客
Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情, 于是在它的基础上包装了一下, 提供了一套更好用的客户端框架. Netflix在用ZooKeeper的过程中遇到的问题, 我们也遇到了, 所以开始研究一下, 首先从他在github上的源码, wiki文档以及Netflix的技术blog入手. .

服务发现:Zookeeper vs etcd vs Consul

- - 企业架构 - ITeye博客
服务发现:Zookeeper vs etcd vs Consul. 【编者的话】本文对比了Zookeeper、etcd和Consul三种服务发现工具,探讨了最佳的服务发现解决方案,仅供参考. 如果使用预定义的端口,服务越多,发生冲突的可能性越大,毕竟,不可能有两个服务监听同一个端口. 管理一个拥挤的比方说被几百个服务所使用的所有端口的列表,本身就是一个挑战,添加到该列表后,这些服务需要的数据库和数量会日益增多.

基于 Consul 的 Docker Swarm 服务发现

- - IT瘾-dev
基于 Consul 的 Docker Swarm 服务发现. 2017 年 1 月 10 日发布. Docker 是一种新型的虚拟化技术,它的目标在于实现轻量级操作系统的虚拟化. 相比传统的虚拟化方案,Docker. 虚拟化技术有一些很明显的优势:启动容器的速度明显快于传统虚拟化技术,同时创建一台虚拟机占用的资源也要远远小于传统的虚拟技术.

Apach警告Web Server发现拒绝服务漏洞

- coofucoo - Solidot
Apache发出警告,Apache HTTPD Web Server中发现拒绝服务漏洞,受影响的版本包括Apache 1.3分支和Apache 2分支的所有版本. Apache表示将在未来48小时内发布补丁. 名叫Apache Killer的攻击工具上周五发布在Full Disclosure邮件列表.

Marathon 服务发现及负载均衡 marathon-lb

- - 企业架构 - ITeye博客
       从官网摘抄了Mesos-DNS的缺陷,也是选择使用marathon-lb做服务发现和负载均衡的原因.        DNS does not identify service ports, unless you use an SRV query; most apps are not able to use SRV records “out of the box.”.

Architect_019:如何发现微服务?(摘录+整理)

- - 热爱Java ,热爱生活
微服务的实例的网络位置都是动态分配的,而且因为扩展、失效和升级等需求,服务实例会经常动态改变,因此,需要一种更加复杂的服务发现机制. 目前有两大类服务发现模式:客户端发现和服务端发现. 当使用客户端发现模式时,客户端负责决定相应服务实例的网络位置,并且对请求实现负载均衡. 客户端从一个服务注册服务中查询,其中是所有可用服务实例的库.

Kubernetes中的服务发现与负载均衡

- - Feisky's Blog
Kubernetes在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了Service资源,并通过kube-proxy配合cloud provider来适应不同的应用场景. 随着kubernetes用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制. 目前,kubernetes中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:.