通过ribbon 根据服务名获取所有服务实例的IP和端口列表
代码使用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和端口列表的更多相关文章
- JavaWeb 获取请求网络协议、IP、端口号、项目根路径
JavaWeb 获取请求网络协议.IP.端口号.项目根路径 CreateTime--2018年6月1日16点32分 Author:Marydon 1.需求 在项目中,需要使用Java向本程序发送r ...
- js 获取请求网络协议、IP、端口号、项目名称
js 获取请求网络协议.IP.端口号.项目名称 CreationTime--2018年6月19日15点54分 Author:Marydon /** * 获取url请求前缀 * @return ht ...
- python根据服务名获取服务启动路径
#coding=utf8 import _winreg as winreg class Win32Environment: """Utility class to get ...
- 在java中获取URL的域名或IP与端口
package com.xxl.sso.sample; import java.net.URI; import java.net.URISyntaxException; public class te ...
- Oracle配置本地网络服务名
Oracle安装完成后,可以使用客户端自带的的网络配置向导(Net Configuration Assistant)进行配置 1.启动Net Configuration Assistant.选择&qu ...
- oracle 服务名 数据库名 实例名
服务名 show parameter service_name 实例名 show parameter instance 数据库名 show parameter db conn username/pas ...
- RestTemplate工具类根据服务名发送请求
要使用RestTemplate 根据服务名发送请求的话需要 使用 @LoadBalanced 这个注解,用了这个注解的RestTemplate就不用使用 ip 来请求了,首先要创建一个配置类 i ...
- SpringCloud微服务(02):Ribbon和Feign组件,实现服务调用的负载均衡
本文源码:GitHub·点这里 || GitEE·点这里 一.Ribbon简介 1.基本概念 Ribbon是一个客户端的负载均衡(Load Balancer,简称LB)器,它提供对大量的HTTP和TC ...
- Python网络编程——通过指定的端口和协议找到服务名
1.通过指定的端口和协议找到对应的服务名,采用socket中getservbyprot()函数实现. import socket def find_service_name(): protocolna ...
随机推荐
- [转]mysql变量使用总结
From : http://www.cnblogs.com/wangtao_20/archive/2011/02/21/1959734.html set语句的学习: 使用select定义用户变量的实践 ...
- Asp.Net MVC2.0 Url 路由入门---实例篇 【转】
本篇主要讲述Routing组件的作用,以及举几个实例来学习Asp.Net MVC2.0 Url路由技术. 接着上一篇开始讲,我们在Global.asax中注册一条路由后,我们的请求是怎么转到相应的Vi ...
- 深度学习Github排名,很不错的介绍
今天看到这篇文章,把深度学习github排名靠前的项目,介绍了一下,很不错: https://blog.csdn.net/yH0VLDe8VG8ep9VGe/article/details/81611 ...
- 算法:快速排序实现 & 定制比较函数
1. 快速排序基本算法 #include<stdio.h> ; int quick_sort(int *a, int start, int end){ if (start >= en ...
- C#中转义字符[转]
https://www.cnblogs.com/muran/p/3174865.html 编程中很多细节问题我们都要十分的注意,要不一个小小的字母错误就能引起程序的无法运行. C#中转义字符分2中,一 ...
- 大数据开发实战:Stream SQL实时开发一
1.流计算SQL原理和架构 流计算SQL通常是一个类SQL的声明式语言,主要用于对流式数据(Streams)的持续性查询,目的是在常见流计算平台和框架(如Storm.Spark Streaming.F ...
- Docker worker nodes shown as “Down” after re-start
After docker is shutdown, the worker node changes its status to Down, but availability remains at A ...
- 在CentOS 7上安装Nginx服务器
下面我就我在CentOS上安装Nginx经验做简单的记录,以备后查. 1.下载nginx-release包 以CentOS 7为例,下载nginx软件包:http://nginx.org/packag ...
- jdbc:initialize-database标签的研究
在spring的applicationContext.xml中如果引入了:<?xml version="1.0" encoding="UTF-8"?> ...
- @SuppressLint("NewApi")和@TargetApi()的区别
在Android代码中,我们有时会使用比我们在AndroidManifest中设置的android:minSdkVersion版本更高的方法,此时编译器会提示警告, 解决方法是在方法上加上@Suppr ...