代码使用SpringCloud版本E3

业务场景:

今天遇到一个业务场景,要求根据服务名获取当前微服务集群中所有的对应服务实例的IP和端口,通过分析源码推算出了写法。

原理简述:

如果代码中引入了spring-cloud-netflix-core(版本1.4.4.RELEASE),则在代码初始化的时候,会通过RibbonAutoConfiguration类创建一个SpringClientFactory的bean,通过该bean可以获取服务实例的IP和端口列表。

代码中的 DomainExtractingServerList对象 是 DynamicServerListLoadBalancer 类中的属性,该属性保存的是全量的服务实例,不过却是私有的,所以只能通过反射来获取了。

具体代码:

  1. package com.liuyx;
  2.  
  3. import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
  4. import com.netflix.loadbalancer.ILoadBalancer;
  5. import com.netflix.loadbalancer.Server;
  6. import com.netflix.loadbalancer.ServerList;
  7. import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
  8. import org.springframework.boot.autoconfigure.SpringBootApplication;
  9. import org.springframework.boot.builder.SpringApplicationBuilder;
  10. import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
  11. import org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList;
  12. import org.springframework.context.ApplicationContext;
  13.  
  14. import java.lang.reflect.Field;
  15. import java.util.List;
  16.  
  17. /**
  18. * Created by liu.yuxiang on 2017/10/12.
  19. */
  20. @SpringBootApplication//(exclude = {ConfigClientAutoConfiguration.class})
  21. public class PortalZuulApplication {
  22.  
  23. public static void main(String[] args) {
  24. ApplicationContext ctx = new SpringApplicationBuilder(PortalZuulApplication.class).web(true).run(args);
  25.  
  26. SpringClientFactory springClientFactory = ctx.getBean(SpringClientFactory.class);
  27. ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer("[服务名]");
  28. List<Server> servers = loadBalancer.getReachableServers();
  29. for(Server server:servers){
  30. //如果服务有设置zone,此处获取的可能并不是所有的实例
  31. System.out.println("---:"+server.getHostPort());
  32. }
  33.  
  34. DynamicServerListLoadBalancer<DiscoveryEnabledServer> dynamicServerListLoadBalancer = (DynamicServerListLoadBalancer)loadBalancer;
  35.  
  36. ServerList<DiscoveryEnabledServer> serverListImpl = dynamicServerListLoadBalancer.getServerListImpl();
  37.  
  38. DomainExtractingServerList domainExtractingServerList1 = (DomainExtractingServerList) serverListImpl;
  39.  
  40. try {
  41. Field field = domainExtractingServerList1.getClass().getDeclaredField("list");
  42. field.setAccessible(true);
  43. ServerList<DiscoveryEnabledServer> list = (ServerList<DiscoveryEnabledServer>)field.get(domainExtractingServerList1);
  44.  
  45. for(DiscoveryEnabledServer server:list.getUpdatedListOfServers()){
  46. //此处获取的是所有的实例
  47. System.out.println("%%%:"+server.getHostPort());
  48. }
  49.  
  50. /*for(DiscoveryEnabledServer server:list.getInitialListOfServers()){
  51. System.out.println("+++:"+server.getHostPort());
  52. }*/
  53. } catch (Exception e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. }

代码中的"[服务名]"请换成你自己的。

因项目中使用了zone(即 eureka.instance.metadata-map.zone=xxx),所以只能通过反射,才能获取真正的所有服务实例,否则只能获取zone为xxx的服务实例。

如果还不明白,参看 区域亲和

通过ribbon 根据服务名获取所有服务实例的IP和端口列表的更多相关文章

  1. JavaWeb 获取请求网络协议、IP、端口号、项目根路径

      JavaWeb 获取请求网络协议.IP.端口号.项目根路径 CreateTime--2018年6月1日16点32分 Author:Marydon 1.需求 在项目中,需要使用Java向本程序发送r ...

  2. js 获取请求网络协议、IP、端口号、项目名称

      js 获取请求网络协议.IP.端口号.项目名称 CreationTime--2018年6月19日15点54分 Author:Marydon /** * 获取url请求前缀 * @return ht ...

  3. python根据服务名获取服务启动路径

    #coding=utf8 import _winreg as winreg class Win32Environment: """Utility class to get ...

  4. 在java中获取URL的域名或IP与端口

    package com.xxl.sso.sample; import java.net.URI; import java.net.URISyntaxException; public class te ...

  5. Oracle配置本地网络服务名

    Oracle安装完成后,可以使用客户端自带的的网络配置向导(Net Configuration Assistant)进行配置 1.启动Net Configuration Assistant.选择&qu ...

  6. oracle 服务名 数据库名 实例名

    服务名 show parameter service_name 实例名 show parameter instance 数据库名 show parameter db conn username/pas ...

  7. RestTemplate工具类根据服务名发送请求

    要使用RestTemplate 根据服务名发送请求的话需要 使用  @LoadBalanced  这个注解,用了这个注解的RestTemplate就不用使用  ip 来请求了,首先要创建一个配置类 i ...

  8. SpringCloud微服务(02):Ribbon和Feign组件,实现服务调用的负载均衡

    本文源码:GitHub·点这里 || GitEE·点这里 一.Ribbon简介 1.基本概念 Ribbon是一个客户端的负载均衡(Load Balancer,简称LB)器,它提供对大量的HTTP和TC ...

  9. Python网络编程——通过指定的端口和协议找到服务名

    1.通过指定的端口和协议找到对应的服务名,采用socket中getservbyprot()函数实现. import socket def find_service_name(): protocolna ...

随机推荐

  1. Sklearn实现逻辑回归

    方法与参数 LogisticRegression类的各项参数的含义 class sklearn.linear_model.LogisticRegression(penalty='l2', dual=F ...

  2. POJ训练计划2528_Mayor&#39;s posters(线段树/成段更新+离散化)

    解题报告 id=2528">地址传送门 题意: 一些海报,覆盖上去后还能看到几张. 思路: 第一道离散化的题. 离散化的意思就是区间压缩然后映射. 给你这么几个区间[1,300000] ...

  3. 哈,今天终于在电脑上吧oracle给装上了

    哈,今天终于在电脑上吧oracle给装上了

  4. WinPcap权威指南(三):ARP协议

    ARP协议在局域网内使用的非常广泛,它的数据包类型分为请求包和答复包.Windows系统内部有一个缓冲区,保存了最近的ARP信息,可以在cmd下使用命令arp -a来显示目前的缓存,或者使用命令arp ...

  5. (十一) 整合spring cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  6. qt文字改变方向

    QPainter painter(this);             QFont font("Courier", 24);             painter.setFont ...

  7. 前后端协调处理checkbox

    需求:页面属于一个弹出窗体,查询结果,用checkbox展示,选择后,把选中的结果传递给调用页面. 由于要取得后端写的checkbox控件的值,所以在后端处理最后的提交事件,用这个语句把结果传递到页面 ...

  8. 如何拷贝一个wchar_t类型的字符串

    Do this, wchar_t clone[260]; wcscpy(clone,szPath); Or, if you want to allocate memory yourself, wcha ...

  9. 25个Web前端开发工程师必看的国外大牛和酷站

    逛了一周国外大牛们的博客与酷站,真是满满的钦佩.震撼.羡慕.惊喜………… Web设计是一个不断变化的领域,因此掌握最新的发展趋势及技术动向对设计师来说非常重要.无论是学习新技术,还是寻找免费资源与工具 ...

  10. Android 为何比 iOS 卡?【转载】

    Android 卡是必须的,当你的手机装了 20 多个 app,那不卡才叫见鬼了呢,我手机微信都打不开,手机直接自动重启啦~哪种东西生来就是完美的呢?即便是台式机,也是越用越慢.换句话,如果没有特别原 ...