代码使用SpringCloud版本E3

业务场景:

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

原理简述:

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

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

具体代码:

package com.liuyx;

import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList;
import org.springframework.context.ApplicationContext; import java.lang.reflect.Field;
import java.util.List; /**
* Created by liu.yuxiang on 2017/10/12.
*/
@SpringBootApplication//(exclude = {ConfigClientAutoConfiguration.class})
public class PortalZuulApplication { public static void main(String[] args) {
ApplicationContext ctx = new SpringApplicationBuilder(PortalZuulApplication.class).web(true).run(args); SpringClientFactory springClientFactory = ctx.getBean(SpringClientFactory.class);
ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer("[服务名]");
List<Server> servers = loadBalancer.getReachableServers();
for(Server server:servers){
//如果服务有设置zone,此处获取的可能并不是所有的实例
System.out.println("---:"+server.getHostPort());
} DynamicServerListLoadBalancer<DiscoveryEnabledServer> dynamicServerListLoadBalancer = (DynamicServerListLoadBalancer)loadBalancer; ServerList<DiscoveryEnabledServer> serverListImpl = dynamicServerListLoadBalancer.getServerListImpl(); DomainExtractingServerList domainExtractingServerList1 = (DomainExtractingServerList) serverListImpl; try {
Field field = domainExtractingServerList1.getClass().getDeclaredField("list");
field.setAccessible(true);
ServerList<DiscoveryEnabledServer> list = (ServerList<DiscoveryEnabledServer>)field.get(domainExtractingServerList1); for(DiscoveryEnabledServer server:list.getUpdatedListOfServers()){
//此处获取的是所有的实例
System.out.println("%%%:"+server.getHostPort());
} /*for(DiscoveryEnabledServer server:list.getInitialListOfServers()){
System.out.println("+++:"+server.getHostPort());
}*/
} catch (Exception e) {
e.printStackTrace();
}
}
}

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

因项目中使用了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. 5G与TCP/IP

    众所周知,4G LTE全面IP化,上层传输走的是TCP/IP协议(如下图). ▲LTE用户面协议构架 但是,我们熟悉的这个构架并没有发挥出移动网络的全部潜力,甚至阻碍了未来网络的发展. 1  TCP/ ...

  2. Understanding Linux CPU stats

    Your Linux server is running slow, so you follow standard procedure and run top. You see the CPU met ...

  3. 在EntityFramework6中执行SQL语句【转】

    在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有操作.这一节我来介绍一下如何使用在EF6中执行SQL语句. 你可能要问,我用EF不就为了避免写SQL吗?如 ...

  4. Unhandled Exception: System.BadImageFormatException: Could not load file or assembly (2008R2配置x64website)

    .NET Error Message: Unhandled Exception: System.BadImageFormatException: Could not load file or asse ...

  5. Solr搜索结果说明 (转)

    在admin页面,输入相关内容后,会返回xml格式的内容.说明如下: <?xml version="1.0" encoding="UTF-8"?> ...

  6. Deformable Convolutional Networks-v1-v2(可变形卷积网络)

    如何评价 MSRA 视觉组最新提出的 Deformable ConvNets V2? <Deformable Convolutional Networks>是一篇2017年Microsof ...

  7. 与IE的战斗

    对第2版的改进,工作量几乎都在UI上,不断的写css,写js,还别说,总体挺愉快的.特别是把360浏览器用顺了之后,烦人的无法刷新问题也不能困扰我了,改了js或者css文件的话,只要清除一下缓存,就可 ...

  8. 用Telnet测试服务器的端口是否开通

      可以用telnet测试远程服务器的端口是否开通,格式如下: telnet <server name> <port number> 例如: Telnet tserv 3389 ...

  9. phpmyadmin误删表后如何恢复

    用mysqlbinlog php处理代码: 将mysql-bin.xxxxxx文件导出为可读文本: <?php //导出mysql-bin.000xxx文件为可读性txt文本 //0为执行成功, ...

  10. ZH奶酪:AngularJS/JavaScript上传图片【PC端】

    [功能介绍] 类似与修改个人信息的时候,点击头像,就可以完成选择照片.上传照片等步骤达到替换头像的目的. [运行流程] (1)点击头像 (2)选择头像 (3)点击“完成”,上传头像 1.HTML图片部 ...