https://fobject.iteye.com/blog/2294728

Zookeeper & Curator 服务注册 
curator是最简单的Zookeeper客户端

Curator主要组件 
Recipes   (扩展:包括分布式锁、队列、选举等) 
Framework  (框架) 
Utilities  (工具) 
Client (客户端) 
Errors  (错误处理) 
另外Curator提供了一些扩展库,比如用于服务注册的curator-x-discovery

服务定义  ServiceInstance 
Curator 中使用可以使用ServiceInstance作为服务定义对象 
通常一个服务对象具有服务名、服务id、地址、端口和有效数据等属性, 
下面就是ServiceInstance类的变量定义。

Java代码  
  1. public class ServiceInstance<T> {
  2. private final String name;
  3. private final String id;
  4. private final String address;
  5. private final Integer port;
  6. private final Integer sslPort;
  7. private final T payload;
  8. private final long registrationTimeUTC;
  9. private final ServiceType serviceType;
  10. private final UriSpec uriSpec;
  11. ...
  12. }

服务注册过程就是将ServiceInstance实例写到Zookeeper层次结构中,服务名name会生成一个ZkNode,id会生成这个name下孩子节点,在注册的时候会指定根路径,所以注册之后的服务在zookeeper中如下图所示

根路径(注册时指定) 
|_____name1 //服务名1 
|        |______id1->序列化ServiceInstance1 
| |______id2->序列化ServiceInstance2 

|_____name2 //服务名2 
|        |______id1->序列化ServiceInstance1 
| |______id2->序列化ServiceInstance2 

可以先通过客户端连接到本地zookeeper查看下具体的服务注册情况,其注册在/###/services/路径下,会发现有很多服务,再进服务查看可以看到这个服务下有多少个实例,其节点为其id(如果服务未设置id,使用的是默认随机生成的字符串)。 
要注意到是服务在注册时生成的name服务名节点是持久的节点,而服务名下面的实例id节点是临时节点,正常服务结束,可以通过提供的相关api来删除对应的节点,临时节点能保证注册服务的程序异常退出或失去连接后也能做到将服务节点摘除。

构造服务实例的方法很简单,可以通过ServiceInstance的build方法进行建造。 
在练习中定义了一个简单的服务业务类XServInstance

Java代码  
  1. public class XServInstance implements Serializable{
  2. private  String id;
  3. private  String name;
  4. private  String path;
  5. get&set()...
  6. }

建造ServiceInstance的代码如下:

Java代码  
  1. ServiceInstance<XServInstance> serviceInstance= ServiceInstance.<XServInstance>builder()
  2. .id(instance.getId())
  3. .name(instance.getName())
  4. .payload(instance).build();

服务注册  ServiceDiscovery 
Curator使用ServiceDiscovery进行服务注册,可以把它认为是服务管理中心,通过它也能查找我们的服务。ServiceDiscovery同样采用建造者方式,由ServiceDiscoveryBuilder进行构造,在构造完成之后需要调用start方法!SERV_PAHT指定我们服务需要注册在zookeeper的哪个目录

Java代码  
  1. JsonInstanceSerializer<XServInstance> serializer=new JsonInstanceSerializer<XServInstance>(XServInstance.class);
  2. serviceDiscovery= ServiceDiscoveryBuilder.builder(XServInstance.class)
  3. .basePath(SERV_PATH)
  4. .client(client)
  5. .serializer(serializer)
  6. .build();
  7. serviceDiscovery.start();

client是curator的zookeeper客户端,通过下面方式构造:

Java代码  
  1. RetryPolicy retryPolicy=new RetryOneTime(1000);
  2. //CONNECT_STR : "127.0.0.1:2181"
  3. client= CuratorFrameworkFactory.newClient(CONNECT_STR,retryPolicy);
  4. client.start()//必须调用

注册服务的代码就一行:

Java代码  
  1. serviceDiscovery.registerService(serviceInstance);

此时服务已注册,在程序未退出时查看SERV_PATH下的内容即注册服务serviceInstance的name,再下一层就是id了,如果同一个服务注册了多个,则会有多个id(注册id相同只会有一个)。退出程序之后,由其注册的id也就没了。 
ServiceDiscovery除了注册服务,同时也能查询服务,其三个主要的查询方法如下:

  • +  Collection<String> queryForNames()  //查询所有服务名
  • +  Collection<ServiceInstance<T>>  queryForInstances(String name)  //查询指定服务名下的所有服务实例
  • +  ServiceInstance<T> queryForInstance(String name, String id)      //根据服务名和id查询服务实例

服务提供  ServiceProvider 
这一步是Curator自带的服务提供方式,也可以不采用自带的服务提供者,而是通过ServiceDiscovery查询(queryForInstances)到服务之后,通过自己的策略进行服务选择(后期待续)。这里直接使用curator现成的服务提供者。

服务提供者的构造通过serviceDiscovery内部的建造者方法进行构造,同样必须先start 
需要注意的是providerStrategy提供策略,对服务提供者设置一个服务选择策略,因为同一个服务名下有很多具体服务实例,具体选择哪一个可以由该策略决定: 
常用的有RoundRobinStrategy 轮询,RandomStrategy 随机选择 ,StickyStrategy 粘性策略(总是选择同一个,没试过比较特殊,可能适用于某些服务调用者和提供者需要记录什么调用记录的情况下吧)

Java代码  
  1. ServiceProvider servPro = serviceDiscovery.serviceProviderBuilder()
  2. .serviceName(servName)
  3. .providerStrategy(new RoundRobinStrategy<XServInstance>())
  4. .build();
  5. servPro.start();

获取一个服务通过以下方式进行获取

Java代码  
  1. ServiceInstance<XServInstance> serviceInstance=servPro.getInstance();

.

最后附上本练习简单的服务注册中心代码和测试代码

Java代码  
  1. public class XServCenter {
  2. public  static final  String SERV_PATH="/myServices";
  3. ServiceDiscovery<XServInstance> serviceDiscovery ;
  4. Map<String,ServiceProvider> providerMap=new HashMap<String, ServiceProvider>();
  5. public  void init(CuratorFramework client) throws Exception {
  6. JsonInstanceSerializer<XServInstance> serializer=new JsonInstanceSerializer<XServInstance>(XServInstance.class);
  7. serviceDiscovery= ServiceDiscoveryBuilder.builder(XServInstance.class)
  8. .basePath(SERV_PATH)
  9. .client(client)
  10. .serializer(serializer)
  11. .build();
  12. serviceDiscovery.start();
  13. }
  14. public  void regist(XServInstance instance) throws Exception {
  15. ServiceInstance<XServInstance> serviceInstance= ServiceInstance.<XServInstance>builder()
  16. .id(instance.getId())
  17. .name(instance.getName())
  18. .payload(instance).build();
  19. serviceDiscovery.registerService(serviceInstance);
  20. }
  21. public  void list() throws Exception {
  22. Collection<String> servNames=serviceDiscovery.queryForNames();
  23. for(String servName:servNames){
  24. Collection<ServiceInstance<XServInstance>> instances=serviceDiscovery.queryForInstances("/"+servName);
  25. System.out.println(servName);
  26. for(ServiceInstance<XServInstance> instance:instances){
  27. System.out.println("------- : "+instance.getId());
  28. }
  29. }
  30. }
  31. public  void getServiceByName(String servName) throws Exception {
  32. ServiceProvider servPro =providerMap.get(servName);
  33. if (servPro==null) {
  34. servPro = serviceDiscovery.serviceProviderBuilder()
  35. .serviceName(servName) //RandomStrategy StickyStrategy
  36. .providerStrategy(new RoundRobinStrategy<XServInstance>())
  37. .build();
  38. servPro.start();
  39. providerMap.put(servName,servPro);
  40. }
  41. ServiceInstance<XServInstance> serviceInstance=servPro.getInstance();
  42. System.out.println("getServiceByName  "+serviceInstance.getId());
  43. }

Test

Java代码  
  1. public class ServTest {
  2. public  static  final String CONNECT_STR="127.0.0.1:2181";
  3. public static CuratorFramework client;
  4. public  static  void main(String args[]) throws Exception {
  5. RetryPolicy retryPolicy=new RetryOneTime(1000);
  6. client= CuratorFrameworkFactory.newClient(CONNECT_STR,retryPolicy);
  7. if(client==null) return;
  8. client.start();
  9. XServCenter xServCenter=new XServCenter();
  10. xServCenter.init(client);
  11. Runtime.getRuntime().addShutdownHook(new Thread(){
  12. public void run() {
  13. CloseableUtils.closeQuietly(client);
  14. }
  15. });
  16. for(int i=0;i<10;i++) {
  17. for(int j=0;j<10;j++) {
  18. XServInstance xServInstance = new XServInstance();
  19. xServInstance.setId("serv_id_" + i+"_"+j);
  20. xServInstance.setName("serv_name_" + i);
  21. xServCenter.regist(xServInstance);
  22. }
  23. }
  24. System.out.println("#####list######");
  25. xServCenter.list();
  26. for(int i=0;i<1000;i++) {
  27. xServCenter.getServiceByName("serv_name_1");
  28. Thread.sleep(500);
  29. }
  30. Thread.sleep(600000);
  31. }
  32. }

转载于:https://www.cnblogs.com/davidwang456/articles/10600349.html

zookeeper curator 服务注册相关推荐

  1. Web Api 基于Zookeeper的服务注册与发现

    差异 基于Nginx的服务提供和消费 基于zookeeper的服务注册和发现 zk的负载均衡是可以调控,nginx只是能调权重,其他需要可控的都需要自己写插件:但是nginx的吞吐量比zk大很多,可以 ...

  2. Zookeeper实现服务注册发现

    服务注册中心 ​ 之所以需要访问注册和服务发现是因为分布式系统中,服务之间需要相互调用,但若每个服务自己维护一份依赖的服务信息的话,就显得很麻烦,且自身维护的数据无法保证其实时性,当依赖的服务信息发生 ...

  3. 基于ZooKeeper的服务注册实现

    简介 本文介绍在Spring Boot环境下,使用ZooKeeper来注册服务.在本地环境搭建了ZooKeeper的伪集群环境. 本文参考了<架构探险>轻量级微服务架构 这本书. 搭建Zo ...

  4. zookeeper实现服务注册与发现

    在分布式架构的系统中,系统经常被暴露为服务以供其他系统调用,这也是SOA或微服务架构常用的模式. 为了使服务之间能够互相通信,需要有一个协调系统来管理这些服务,以便这些服务能够互相找到对方,这就是服务 ...

  5. 使用Zookeeper实现服务注册中心-《架构探险-从零开始写分布式服务框架》读书笔记

    前言 最近在看<架构探险-从零开始写分布式服务框架>,对于分布式框架的入门级选手还是挺合适的,扫盲.对分布式服务框架中的基本概念:RPC.SOA.序列化.Spring集成RPC.ZooKe ...

  6. 为什么我们要把服务注册发现改为阿里巴巴的Nacos而不用 ZooKeeper?

    站在未来的路口,回望历史的迷途,常常会很有意思,因为我们会不经意地兴起疯狂的念头,例如如果当年某事提前发生了,而另外一件事又没有发生会怎样?一如当年的奥匈帝国皇位继承人斐迪南大公夫妇如果没有被塞尔维亚 ...

  7. 8、Zookeeper服务注册与发现原理浅析

    了解Zookeeper的我们都知道,Zookeeper是一种分布式协调服务,在分布式应用中,主要用来实现分布式服务的注册与发现以及分布式锁,本文我们简单介绍一下Zookeeper是如何实现服务的注册与 ...

  8. Zookeeper服务注册与发现

    Zookeeper作为服务注册与发现的解决方案,它有如下优点: 1. 它提供的简单API 2. 已有互联网公司(例如:Pinterest,Airbnb)使用它来进行服务注册与发现 3. 支持多语言的客 ...

  9. 说得太好了!阿里巴巴为什么不用 ZooKeeper 做服务发现?

    作者:坤宇 yq.aliyun.com/articles/601745?scm=20140722.184.2.173 站在未来的路口,回望历史的迷途,常常会很有意思,因为我们会不经意地兴起疯狂的念头, ...

最新文章

  1. java中String对象和String变量
  2. 版本控制8(译文) -(完)
  3. python读取文件r_python 文件读写模式r,r+,w,w+,a,a+的区别(附代码示例)
  4. Zigbee音频, 6LowPAN, IEEE 802
  5. 一套比较完整的前端技术选型,需要规整哪些东西,你知道不?
  6. 1Python全栈之路系列之MySQL数据库基本操作
  7. Compile、Make和Build的区别(as make, build, clean, run)
  8. Bluetooth技术学习笔记 ——RFCOMM(2)
  9. Word的”交叉引用“和”插入题注“快捷键设置
  10. 51单片机入门之点亮发光二极管
  11. 水星路由器登录界面找不到服务器,水星路由器管理页面怎么登陆不进去? | 192路由网...
  12. 难过!能不能放下抢票套路,我只想买好好回家过年!我在网上抢火车票:多加了100元的加速包,却依然买不到票...
  13. PlayCanvas学习教程总结
  14. 智能座舱软件平台EX5.0发布,量“声”打造音视觉融合交互体验
  15. 使用neon实现RGB888转RGB565
  16. 武汉迷萌!3D《巅峰漂移》技术分享
  17. 432 4.3.2 STOREDRV.Deliver; recipient thread limit exceeded
  18. 有时候缘分来了,挡也挡不住,我们终究能等到对的那个人。
  19. 刘慈欣新作《黄金原野》与 区块链
  20. 计算机二级考试试题c语言,2014年计算机二级c考试试题 1

热门文章

  1. 简单选择排序 c代码
  2. 计算机专业2016高考录取分数线,中国科学院大学计算机科学与技术专业2016年在江苏理科高考录取最低分数线...
  3. java遍历集合选择题_Java集合知识测试B
  4. lighttpd+fastcgi 返回500错误码_阿根廷著名电视减肥冠军去世 临终前体重达到500公斤...
  5. 关闭oracle服务 linux,Linux下启动和关闭Oracle服务与数据库
  6. java如何绘制图表_java绘制excel图表(jxcell)
  7. ios开发返回按钮消失_iOS开发之自定义导航栏返回按钮右滑返回手势失效的解决...
  8. sql between包括两端吗_简单查询-SQL
  9. flutter 局部状态和全局状态区别_Flutter状态管理
  10. java rgb hsl_RGB、HSB、HSL 互相转换算法