博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何动态获取Dubbo服务提供方地址列表
阅读量:7081 次
发布时间:2019-06-28

本文共 3417 字,大约阅读时间需要 11 分钟。

一、前言

dubbo框架本身提供了丰富的负载均衡策略,比如轮询、随机、最少活跃调用数、一致性hash等,但是有时候我们需要自己根据业务指定某个ip来进行调用。要指定ip进行调用就需要先知道服务提供者的ip。本文我们先来探讨第一步,当服务注册中心使用zookeeper时候如何获取某一个服务的提供端的地址列表。

二、实现

我们知道当服务提供方启动时候,会注册服务到服务注册中心,本文我们通用zookeeper,比如服务com.books.dubbo.demo.api.GreetingService则注册到zk后,是下面树形结构

那么当消费端启动时候会去zookeeper上订阅path为/dubbo/com.books.dubbo.demo.api.GreetingService/providers下面的信息,也就是服务提供者列表信息,那么我们就可以基于这个原理来获取某一个服务提供者列表,然后对信息进行过滤加工,并且注册一个监听器,当服务提供者机器增减后,动态更新保存的地址列表。

基于上面原理实现代码如下:

public class ZookeeperIpList {    private String dataId = "com.books.dubbo.demo.api.GreetingService/providers:1.0.0";    private URL CONSUMER_URL;    private static final Joiner j = Joiner.on("|").useForNull("nil");    public final List
getIpList() { return ipList; } private volatile List
ipList = new ArrayList
(); //对获取的列表内容进行过滤 private static List
toUrlsWithoutEmpty(URL consumer, List
providers) { List
urls = new ArrayList
(); if (providers != null && providers.size() > 0) { urls = providers.stream().map(provider -> URL.decode(provider)).filter(provider -> provider.contains("://")) .map(provider -> URL.valueOf(provider)).filter(url -> UrlUtils.isMatch(consumer, url)) .collect(Collectors.toList()); } return urls; } // 解析服务提供者地址列表为ip:port格式 private void parseIpList(List
ipSet) { List
urlList = toUrlsWithoutEmpty(CONSUMER_URL, ipSet); final List
ipListTemp = urlList.stream().map(url -> url.getAddress()).collect(Collectors.toList()); this.ipList = ipListTemp; } public void init(String zkServerAddr, String zkGroup, String dataId, String serviceGroup) { // 1.参数校验 Assert.notNull(zkServerAddr, "zkServerAddr is null."); Assert.notNull(dataId, "dataId is null."); Assert.notNull(dataId, "zkGroup is null."); Assert.notNull(dataId, "serviceGroup is null."); // 2.拼接订阅的path String[] temp = dataId.split(":"); if (temp.length != 2) { throw new RuntimeException("dataId is illegal"); } this.dataId = "/" + zkGroup + "/" + temp[0] + "/providers"; String consumeUrl = "consumer://127.0.0.1/?group=" + serviceGroup + "&interface=" + temp[0] + "&version=" + temp[1]; CONSUMER_URL = URL.valueOf(consumeUrl); // 3.开启zk,订阅path路径下服务提供者信息,并添加监听器 System.out.println(j.join("init zk ", zkServerAddr, this.dataId, consumeUrl)); ZkClient zkClient = new ZkClient(zkServerAddr); List
list = zkClient.subscribeChildChanges(this.dataId, new IZkChildListener() { @Override public void handleChildChange(String parentPath, List
currentChilds) throws Exception { // 3.1解析服务提供者地址列表 parseIpList(currentChilds); try { System.out.println((j.join("ipList changed:", JSON.json(ipList)))); } catch (IOException e) { } } }); //4. 解析服务提供者ip列表 parseIpList(list); } public static void main(String[] a) throws InterruptedException { ZookeeperIpList zk = new ZookeeperIpList(); zk.init("127.0.0.1:2181", "dubbo", "com.books.dubbo.demo.api.GreetingService:1.0.0", "dubbo"); try { System.out.println((j.join("parseIpList", JSON.json(zk.getIpList())))); } catch (IOException e) { } Thread.currentThread().join(); }}复制代码

如上代码main函数创建了一个ZookeeperIpList对象,并且调用其init方法,参数分别为zk地址,zk分组,服务接口以及版本,服务分组。

init方法内首先拼接要订阅的zk的path,拼接完成后dataid为/dubbo/com.books.dubbo.demo.api.GreetingService/providers,然后创建zkclient订阅该dataid对应的path,并且注册监听器,当path下信息变化后会得到最新列表。

并且使用parseIpList方法解析获取的地址列表为ip:port个数,解析完毕后保存到ipList中。

三、总结

本节介绍了一个简单的基于zookeeper获取服务提供者地址列表的方法,后面我们看如何指定ip进行调用。

转载地址:http://mxjml.baihongyu.com/

你可能感兴趣的文章
linux下网络配置小节[from 老男孩的linux运维笔记]
查看>>
ubuntu--Supervisor进程管理工具
查看>>
amongst/among
查看>>
GUID和自增ID的比较_id/guidid
查看>>
【POJ】【最小生成树】1789 Truck History
查看>>
Adhesive框架系列文章--Mongodb数据服务模块实现(上)
查看>>
C#日期格式转换大全
查看>>
QQ等软件可以联网 网页打不开
查看>>
c++ 使用socket实现C/S端文件的下载传输
查看>>
JMF获取设备列表失败,获取视频设备失败?
查看>>
国内 Mono 相关文章汇总
查看>>
Python模块学习 ---- datetime
查看>>
MS SQL Server Quarter Function
查看>>
VS 2012 的 单元测试 和 测试资源管理器
查看>>
hadoop-集群管理(4)——关键属性
查看>>
SCCM2007
查看>>
从程序员到项目经理(三):认识项目经理
查看>>
Cmake find_package()相关
查看>>
css3简单几步画一个乾坤图
查看>>
【javascript基础】2、函数
查看>>