获取所有的服务实例的简单信息,根据主机名获取某个实例的信息,根据appId查询实例,可能有多个
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
# 高可用注册中心
|
||||
相同的hostname的注册中心eureka会认为是这些euraka在同一台物理机上,这些eureka会一共存储
|
||||
一份注册者的信息,而不是每个注册中心存储一份。所以在同一台机器上模拟高可用注册中心的时候
|
||||
必须修改hosts文件,注册中心使用不同的hostname
|
||||
必须修改hosts文件,注册中心使用不同的hostname
|
||||
|
||||
#### 增加了注册实例查询的restful接口
|
||||
默认的base路径是`/restful/eureka`
|
||||
@@ -41,6 +41,12 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!--common-->
|
||||
<dependency>
|
||||
<groupId>com.micro.fast</groupId>
|
||||
<artifactId>boot-starter-common</artifactId>
|
||||
<version>${micro.fast.version}</version>
|
||||
</dependency>
|
||||
<!--测试-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
+111
-59
@@ -1,5 +1,6 @@
|
||||
package com.micro.fast.eureka.server.controller;
|
||||
|
||||
import com.micro.fast.boot.starter.common.response.ServerResponse;
|
||||
import com.netflix.appinfo.AmazonInfo;
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
@@ -14,28 +15,33 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistry;
|
||||
import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl;
|
||||
import com.netflix.eureka.resources.StatusResource;
|
||||
import com.netflix.eureka.util.StatusInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* restful操作eureka的接口
|
||||
*
|
||||
* @author lsy
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping({"${eureka.restful.path:/restful/eureka}"})
|
||||
@Api(description = "注册中心的restful接口")
|
||||
public class RestfulEurekaController {
|
||||
|
||||
|
||||
@Value("${eureka.restful.path:/restful/eureka}")
|
||||
private String restfulPath = "";
|
||||
private String restfulPath = "/restful/eureka";
|
||||
|
||||
/**
|
||||
* 实例管理对象
|
||||
*/
|
||||
@@ -45,11 +51,64 @@ public class RestfulEurekaController {
|
||||
this.applicationInfoManager = applicationInfoManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详细信息
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps")
|
||||
@ApiOperation("获取所有的服务实例的简单信息")
|
||||
public ServerResponse apps(HttpServletRequest request, HttpServletResponse response) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
//获取所有服务的信息
|
||||
populateApps(map);
|
||||
return ServerResponse.successMsgData("获取所有实例成功", map);
|
||||
}
|
||||
|
||||
@GetMapping("/apps/{instanceId}")
|
||||
@ApiOperation("根据主机名获取某个实例的信息")
|
||||
public ServerResponse getInstance(@PathVariable("instanceId") String instanceId) {
|
||||
InstanceInfo instanceInfo = null;
|
||||
if (StringUtils.isNotBlank(instanceId)){
|
||||
List<Application> sortedApplications = getRegistry().getSortedApplications();
|
||||
boolean isBreak = false;
|
||||
for (Application sortedApplication : sortedApplications) {
|
||||
List<InstanceInfo> instances = sortedApplication.getInstances();
|
||||
for (InstanceInfo instance : instances) {
|
||||
String hostName = instance.getHostName();
|
||||
if (hostName.startsWith(instanceId)){
|
||||
instanceInfo = instance;
|
||||
isBreak = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isBreak){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
return ServerResponse.errorMsg("instanceId不能为空");
|
||||
}
|
||||
|
||||
return ServerResponse.successMsgData("根据主机名获取实例信息成功", instanceInfo);
|
||||
}
|
||||
@GetMapping("/apps/{appId}")
|
||||
@ApiOperation("根据appId查询实例,可能有多个")
|
||||
public ServerResponse getInstancesByAppId(@PathVariable("appId") String appId) {
|
||||
Set<InstanceInfo> instanceInfos = new HashSet<>(10);
|
||||
if (StringUtils.isNotBlank(appId)){
|
||||
List<Application> sortedApplications = getRegistry().getSortedApplications();
|
||||
for (Application sortedApplication : sortedApplications) {
|
||||
List<InstanceInfo> instances = sortedApplication.getInstances();
|
||||
for (InstanceInfo instance : instances) {
|
||||
if (appId.equals(instance.getAppName())){
|
||||
instanceInfos.add(instance);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}else {
|
||||
return ServerResponse.errorMsg("instanceId不能为空");
|
||||
}
|
||||
|
||||
return ServerResponse.successMsgData("根据主机名获取实例信息成功", instanceInfos);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ResponseBody
|
||||
public Map<String, Object> status(HttpServletRequest request, HttpServletResponse response) {
|
||||
@@ -58,26 +117,27 @@ public class RestfulEurekaController {
|
||||
populateApps(map);
|
||||
StatusInfo statusInfo;
|
||||
try {
|
||||
//获取当前注册中心的本身的相信信息
|
||||
statusInfo = new StatusResource().getStatusInfo();
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
//获取当前注册中心的本身的相信信息
|
||||
statusInfo = StatusInfo.Builder.newBuilder().isHealthy(false).build();
|
||||
}
|
||||
map.put("statusInfo", statusInfo);
|
||||
populateInstanceInfo(map, statusInfo);
|
||||
filterReplicas(map, statusInfo);
|
||||
response.setStatus(HttpStatus.SC_OK);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最后注册的实例
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/lastn")
|
||||
public Map<String, Object> lastn(HttpServletRequest request) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
populateBase(request, map);
|
||||
PeerAwareInstanceRegistryImpl registry = (PeerAwareInstanceRegistryImpl) getRegistry();
|
||||
ArrayList<Map<String, Object>> lastNCanceled = new ArrayList<>();
|
||||
@@ -103,14 +163,15 @@ public class RestfulEurekaController {
|
||||
}
|
||||
|
||||
protected void populateBase(HttpServletRequest request, Map<String, Object> model) {
|
||||
model.put("time", new Date());
|
||||
model.put("basePath", "/");
|
||||
model.put("restfulPath", this.restfulPath.equals("/") ? ""
|
||||
: this.restfulPath);
|
||||
populateHeader(model);
|
||||
populateNavbar(request, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加注册中心基础信息
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
private void populateHeader(Map<String, Object> model) {
|
||||
model.put("currentTime", StatusResource.getCurrentTimeAsString());
|
||||
model.put("upTime", StatusInfo.getUpTime());
|
||||
@@ -148,16 +209,22 @@ public class RestfulEurekaController {
|
||||
URI uri = new URI(node.getServiceUrl());
|
||||
String href = scrubBasicAuth(node.getServiceUrl());
|
||||
replicas.put(uri.getHost(), href);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
// ignore?
|
||||
}
|
||||
}
|
||||
model.put("replicas", replicas.entrySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 填所有实例的简单信息
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
private void populateApps(Map<String, Object> model) {
|
||||
//获取实例的详细信息
|
||||
List<Application> sortedApplications = getRegistry().getSortedApplications();
|
||||
//封装成简单的信息
|
||||
ArrayList<Map<String, Object>> apps = new ArrayList<>();
|
||||
for (Application app : sortedApplications) {
|
||||
LinkedHashMap<String, Object> appData = new LinkedHashMap<>();
|
||||
@@ -180,15 +247,13 @@ public class RestfulEurekaController {
|
||||
Integer count = amiCounts.get(ami);
|
||||
if (count != null) {
|
||||
amiCounts.put(ami, count + 1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
amiCounts.put(ami, 1);
|
||||
}
|
||||
count = zoneCounts.get(zone);
|
||||
if (count != null) {
|
||||
zoneCounts.put(zone, count + 1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
zoneCounts.put(zone, 1);
|
||||
}
|
||||
List<Pair<String, String>> list = instancesByStatus.get(status);
|
||||
@@ -203,7 +268,7 @@ public class RestfulEurekaController {
|
||||
ArrayList<Map<String, Object>> instanceInfos = new ArrayList<>();
|
||||
appData.put("instanceInfos", instanceInfos);
|
||||
for (Iterator<Map.Entry<InstanceInfo.InstanceStatus, List<Pair<String, String>>>> iter = instancesByStatus
|
||||
.entrySet().iterator(); iter.hasNext();) {
|
||||
.entrySet().iterator(); iter.hasNext(); ) {
|
||||
Map.Entry<InstanceInfo.InstanceStatus, List<Pair<String, String>>> entry = iter
|
||||
.next();
|
||||
List<Pair<String, String>> value = entry.getValue();
|
||||
@@ -214,18 +279,6 @@ public class RestfulEurekaController {
|
||||
ArrayList<Map<String, Object>> instances = new ArrayList<>();
|
||||
instanceData.put("instances", instances);
|
||||
instanceData.put("isNotUp", status != InstanceInfo.InstanceStatus.UP);
|
||||
|
||||
// TODO
|
||||
|
||||
/*
|
||||
* if(status != InstanceInfo.InstanceStatus.UP){
|
||||
* buf.append("<font color=red size=+1><b>"); }
|
||||
* buf.append("<b>").append(status
|
||||
* .name()).append("</b> (").append(value.size()).append(") - ");
|
||||
* if(status != InstanceInfo.InstanceStatus.UP){
|
||||
* buf.append("</font></b>"); }
|
||||
*/
|
||||
|
||||
for (Pair<String, String> p : value) {
|
||||
LinkedHashMap<String, Object> instance = new LinkedHashMap<>();
|
||||
instances.add(instance);
|
||||
@@ -234,20 +287,19 @@ public class RestfulEurekaController {
|
||||
instance.put("url", url);
|
||||
boolean isHref = url != null && url.startsWith("http");
|
||||
instance.put("isHref", isHref);
|
||||
/*
|
||||
* String id = p.first(); String url = p.second(); if(url != null &&
|
||||
* url.startsWith("http")){
|
||||
* buf.append("<a href=\"").append(url).append("\">"); }else { url =
|
||||
* null; } buf.append(id); if(url != null){ buf.append("</a>"); }
|
||||
* buf.append(", ");
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
// out.println("<td>" + buf.toString() + "</td></tr>");
|
||||
}
|
||||
model.put("apps", apps);
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充当前注册中心的信息
|
||||
*
|
||||
* @param model
|
||||
* @param statusInfo
|
||||
*/
|
||||
private void populateInstanceInfo(Map<String, Object> model, StatusInfo statusInfo) {
|
||||
InstanceInfo instanceInfo = statusInfo.getInstanceInfo();
|
||||
Map<String, String> instanceMap = new HashMap<>();
|
||||
@@ -270,29 +322,29 @@ public class RestfulEurekaController {
|
||||
|
||||
protected void filterReplicas(Map<String, Object> model, StatusInfo statusInfo) {
|
||||
Map<String, String> applicationStats = statusInfo.getApplicationStats();
|
||||
if(applicationStats.get("registered-replicas").contains("@")){
|
||||
if (applicationStats.get("registered-replicas").contains("@")) {
|
||||
applicationStats.put("registered-replicas", scrubBasicAuth(applicationStats.get("registered-replicas")));
|
||||
}
|
||||
if(applicationStats.get("unavailable-replicas").contains("@")){
|
||||
applicationStats.put("unavailable-replicas",scrubBasicAuth(applicationStats.get("unavailable-replicas")));
|
||||
if (applicationStats.get("unavailable-replicas").contains("@")) {
|
||||
applicationStats.put("unavailable-replicas", scrubBasicAuth(applicationStats.get("unavailable-replicas")));
|
||||
}
|
||||
if(applicationStats.get("available-replicas").contains("@")){
|
||||
applicationStats.put("available-replicas",scrubBasicAuth(applicationStats.get("available-replicas")));
|
||||
if (applicationStats.get("available-replicas").contains("@")) {
|
||||
applicationStats.put("available-replicas", scrubBasicAuth(applicationStats.get("available-replicas")));
|
||||
}
|
||||
model.put("applicationStats", applicationStats);
|
||||
}
|
||||
|
||||
private String scrubBasicAuth(String urlList){
|
||||
String[] urls=urlList.split(",");
|
||||
String filteredUrls="";
|
||||
for(String u : urls){
|
||||
if(u.contains("@")){
|
||||
filteredUrls+=u.substring(0,u.indexOf("//")+2)+u.substring(u.indexOf("@")+1,u.length())+",";
|
||||
}else{
|
||||
filteredUrls+=u+",";
|
||||
private String scrubBasicAuth(String urlList) {
|
||||
String[] urls = urlList.split(",");
|
||||
String filteredUrls = "";
|
||||
for (String u : urls) {
|
||||
if (u.contains("@")) {
|
||||
filteredUrls += u.substring(0, u.indexOf("//") + 2) + u.substring(u.indexOf("@") + 1, u.length()) + ",";
|
||||
} else {
|
||||
filteredUrls += u + ",";
|
||||
}
|
||||
}
|
||||
return filteredUrls.substring(0,filteredUrls.length()-1);
|
||||
return filteredUrls.substring(0, filteredUrls.length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user