前言
最近在做一个功能需要获取到在springcloud中所有微服务的接口信息,开始思路一直是在考虑如何通过eureka来获取到这些注册的接口信息,翻看了很多eureka相关的接口,也把相关接口都试了下发现都没办法获取到eureka里注册的服务下的接口,后来突然想到会不会eureka根本就不维护服务下具体接口的信息,于是翻看eureka源码发现果然在eureka中根本不会去维护相关服务节点下的接口状态,这样在eureka中当然就查不到服务接口的信息了。通过这次学习eureka源码也对eureka有了更加深入的理解,eureka在服务治理中,主要负责维护管理每个服务节点的
解决方案
通过eurekaClient获取所有注册application
首先可以通过EurekaClient获取到注册在Eureka上的所有Application,这里的application其实就是我们常说的服务节点,通过eureka的源码我们可以知道eureka只能获取到服务节点的信息,包括服务节点的名称、状态、IP、端口、心跳情况等信息。
Applications applications = eurekaClient.getApplications();
获取到application后可以通过服务节点对象获取到所有的的服务节点信息,获取到服务节点信息后,通过遍历所有的服务节点查询每个服务节点上的swagger接口信息就可以获取到所有接口的细节,将这些接口细节汇总后就可以得到所有微服务接口信息。
注:这么操作的前提是所有服务节点都是在同一个eureka集群中,并且都开启了swagger服务,只有在swagger中注册的接口才可以查询到。
通过swagger接口获取到注册的接口信息
获取到服务节点名称后,就通过swagger接口来查询服务节点下的接口信息,http:// SERVICE-NAME/v2/api-docs
。
下面是测试写的获取当前eureka中注册的所有服务节点下的所有服务接口路径,当然也可以通过swagger返回的接口信息获取到其他的接口信息,你在swagger中能够查询到的接口信息在这里都可以获取到。
@RestController
public class ServiceController {
private final Logger logger = Logger.getLogger(getClass());
@Autowired
private RestTemplate restTemplate;
@Autowired
private EurekaClient eurekaClient;
@RequestMapping(value = "/getMicroServices", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
public String testController1(){
StringBuilder sb = new StringBuilder();
Applications applications = eurekaClient.getApplications();
for(Application application : applications.getRegisteredApplications()) {
try {
//通过swagger查询服务接口的接口来获取该服务节点下的所有服务接口明细
String rsp = restTemplate.getForEntity("http://" + application.getName() + "/v2/api-docs", String.class).getBody();
//使用fastjson进行解析
JSONObject apiObject = JSON.parseObject(rsp);
JSONObject pathsObject = apiObject.getJSONObject("paths");
for (Map.Entry<String, Object> path : pathsObject.entrySet()) {
System.out.println(path.getKey());
}
sb.append(rsp);
}catch(Exception ex){
//这里需要注意对于没有使用swagger的服务是无法调用swagger接口的,会抛出异常,需要对异常捕获后继续执行
continue;
}
}
return sb.toString();
}
}
总结
这个功能不难实现,但是第一次做的时候还是摸索了挺长时间,其实实际代码量并不大,这里做个记录方便其他遇到类似问题的同学能够作为参考。