dashboard: code and document refinement
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
737747a412
commit
b7956c6bb4
|
|
@ -50,7 +50,8 @@ Sentinel 提供了多种规则来保护系统的不同部分。流量控制规
|
||||||
## 3. 配置项
|
## 3. 配置项
|
||||||
|
|
||||||
控制台的一些特性可以通过配置项来进行配置,配置项主要有两个来源:`System.getProperty()` 和 `System.getenv()`,同时存在时后者可以覆盖前者。
|
控制台的一些特性可以通过配置项来进行配置,配置项主要有两个来源:`System.getProperty()` 和 `System.getenv()`,同时存在时后者可以覆盖前者。
|
||||||
> 环境变量因为不支持`.`所以需要将其更换为`_`。
|
|
||||||
|
> 通过环境变量进行配置时,因为不支持 `.` 所以需要将其更换为 `_`。
|
||||||
|
|
||||||
项 | 类型 | 默认值 | 最小值 | 描述
|
项 | 类型 | 默认值 | 最小值 | 描述
|
||||||
--- | --- | --- | --- | ---
|
--- | --- | --- | --- | ---
|
||||||
|
|
@ -61,15 +62,20 @@ sentinel.dashboard.autoRemoveMachineMillis | Integer | 0 | 300000 | 距离最近
|
||||||
|
|
||||||
配置示例:
|
配置示例:
|
||||||
|
|
||||||
命令行
|
- 命令行方式:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
java -Dsentinel.dashboard.app.hideAppNoMachineMillis=60000
|
java -Dsentinel.dashboard.app.hideAppNoMachineMillis=60000
|
||||||
```
|
```
|
||||||
java
|
|
||||||
|
- Java 方式:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
System.setProperty("sentinel.dashboard.app.hideAppNoMachineMillis", "60000");
|
System.setProperty("sentinel.dashboard.app.hideAppNoMachineMillis", "60000");
|
||||||
```
|
```
|
||||||
环境变量
|
|
||||||
|
- 环境变量方式:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sentinel_dashboard_app_hideAppNoMachineMillis=60000
|
sentinel_dashboard_app_hideAppNoMachineMillis=60000
|
||||||
```
|
```
|
||||||
|
|
@ -78,4 +84,3 @@ sentinel_dashboard_app_hideAppNoMachineMillis=60000
|
||||||
|
|
||||||
- [Sentinel 控制台启动和客户端接入](./README.md)
|
- [Sentinel 控制台启动和客户端接入](./README.md)
|
||||||
- [控制台 Wiki](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0)
|
- [控制台 Wiki](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<spring.boot.version>2.0.5.RELEASE</spring.boot.version>
|
<spring.boot.version>2.0.5.RELEASE</spring.boot.version>
|
||||||
<apollo.openapi.version>1.2.0</apollo.openapi.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
@ -39,12 +38,6 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.csp</groupId>
|
|
||||||
<artifactId>sentinel-datasource-nacos</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
|
@ -99,6 +92,20 @@
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- for Nacos rule publisher sample -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.csp</groupId>
|
||||||
|
<artifactId>sentinel-datasource-nacos</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- for Apollo rule publisher sample -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ctrip.framework.apollo</groupId>
|
||||||
|
<artifactId>apollo-openapi</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
@ -109,13 +116,6 @@
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-openapi -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.ctrip.framework.apollo</groupId>
|
|
||||||
<artifactId>apollo-openapi</artifactId>
|
|
||||||
<version>${apollo.openapi.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.stefanbirkner</groupId>
|
<groupId>com.github.stefanbirkner</groupId>
|
||||||
<artifactId>system-rules</artifactId>
|
<artifactId>system-rules</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -34,22 +34,26 @@ import org.springframework.lang.NonNull;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DashboardConfig {
|
public class DashboardConfig {
|
||||||
|
|
||||||
|
public static final int DEFAULT_MACHINE_HEALTHY_TIMEOUT_MS = 60_000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hide app in sidebar when it had no healthy machine after specific period in millis
|
* Hide application name in sidebar when it has no healthy machines after specific period in millisecond.
|
||||||
*/
|
*/
|
||||||
public static final String CONFIG_HIDE_APP_NO_MACHINE_MILLIS = "sentinel.dashboard.app.hideAppNoMachineMillis";
|
public static final String CONFIG_HIDE_APP_NO_MACHINE_MILLIS = "sentinel.dashboard.app.hideAppNoMachineMillis";
|
||||||
/**
|
/**
|
||||||
* remove app when it had no healthy machine after specific period in millis
|
* Remove application when it has no healthy machines after specific period in millisecond.
|
||||||
*/
|
*/
|
||||||
public static final String CONFIG_REMOVE_APP_NO_MACHINE_MILLIS = "sentinel.dashboard.removeAppNoMachineMillis";
|
public static final String CONFIG_REMOVE_APP_NO_MACHINE_MILLIS = "sentinel.dashboard.removeAppNoMachineMillis";
|
||||||
/**
|
/**
|
||||||
* unhealthy millis
|
* Timeout
|
||||||
*/
|
*/
|
||||||
public static final String CONFIG_UNHEALTHY_MACHINE_MILLIS = "sentinel.dashboard.unhealthyMachineMillis";
|
public static final String CONFIG_UNHEALTHY_MACHINE_MILLIS = "sentinel.dashboard.unhealthyMachineMillis";
|
||||||
/**
|
/**
|
||||||
* auto remove unhealthy machine after specific period in millis
|
* Auto remove unhealthy machine after specific period in millisecond.
|
||||||
*/
|
*/
|
||||||
public static final String CONFIG_AUTO_REMOVE_MACHINE_MILLIS = "sentinel.dashboard.autoRemoveMachineMillis";
|
public static final String CONFIG_AUTO_REMOVE_MACHINE_MILLIS = "sentinel.dashboard.autoRemoveMachineMillis";
|
||||||
|
|
||||||
private static final ConcurrentMap<String, Object> cacheMap = new ConcurrentHashMap<>();
|
private static final ConcurrentMap<String, Object> cacheMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
@ -94,7 +98,7 @@ public class DashboardConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getUnhealthyMachineMillis() {
|
public static int getUnhealthyMachineMillis() {
|
||||||
return getConfigInt(CONFIG_UNHEALTHY_MACHINE_MILLIS, 60000, 30000);
|
return getConfigInt(CONFIG_UNHEALTHY_MACHINE_MILLIS, DEFAULT_MACHINE_HEALTHY_TIMEOUT_MS, 30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearCache() {
|
public static void clearCache() {
|
||||||
|
|
|
||||||
|
|
@ -28,40 +28,36 @@ import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.vo.MachineInfoVo;
|
import com.alibaba.csp.sentinel.dashboard.domain.vo.MachineInfoVo;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 这个Controller负责app,机器信息的交互.
|
* @author Carpenter Lee
|
||||||
*/
|
*/
|
||||||
@Controller
|
@RestController
|
||||||
@RequestMapping(value = "/app", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/app")
|
||||||
public class AppController {
|
public class AppController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
AppManagement appManagement;
|
private AppManagement appManagement;
|
||||||
|
|
||||||
@ResponseBody
|
@GetMapping("/names.json")
|
||||||
@RequestMapping("/names.json")
|
public Result<List<String>> queryApps(HttpServletRequest request) {
|
||||||
Result<List<String>> queryApps(HttpServletRequest request) {
|
|
||||||
return Result.ofSuccess(appManagement.getAppNames());
|
return Result.ofSuccess(appManagement.getAppNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
@GetMapping("/briefinfos.json")
|
||||||
@RequestMapping("/briefinfos.json")
|
public Result<List<AppInfo>> queryAppInfos(HttpServletRequest request) {
|
||||||
Result<List<AppInfo>> queryAppInfos(HttpServletRequest request) {
|
|
||||||
List<AppInfo> list = new ArrayList<>(appManagement.getBriefApps());
|
List<AppInfo> list = new ArrayList<>(appManagement.getBriefApps());
|
||||||
Collections.sort(list, Comparator.comparing(AppInfo::getApp));
|
Collections.sort(list, Comparator.comparing(AppInfo::getApp));
|
||||||
return Result.ofSuccess(list);
|
return Result.ofSuccess(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
@GetMapping(value = "/{app}/machines.json")
|
||||||
@RequestMapping(value = "/{app}/machines.json")
|
public Result<List<MachineInfoVo>> getMachinesByApp(@PathVariable("app") String app) {
|
||||||
Result<List<MachineInfoVo>> getMachinesByApp(@PathVariable("app") String app) {
|
|
||||||
AppInfo appInfo = appManagement.getDetailApp(app);
|
AppInfo appInfo = appManagement.getDetailApp(app);
|
||||||
if (appInfo == null) {
|
if (appInfo == null) {
|
||||||
return Result.ofSuccess(null);
|
return Result.ofSuccess(null);
|
||||||
|
|
@ -81,9 +77,8 @@ public class AppController {
|
||||||
return Result.ofSuccess(MachineInfoVo.fromMachineInfoList(list));
|
return Result.ofSuccess(MachineInfoVo.fromMachineInfoList(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
@GetMapping(value = "/{app}/machine/remove.json")
|
||||||
@RequestMapping(value = "/{app}/machine/remove.json")
|
public Result<String> removeMachineById(
|
||||||
Result<String> removeMachineById(
|
|
||||||
@PathVariable("app") String app,
|
@PathVariable("app") String app,
|
||||||
@RequestParam(name = "ip") String ip,
|
@RequestParam(name = "ip") String ip,
|
||||||
@RequestParam(name = "port") int port) {
|
@RequestParam(name = "port") int port) {
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public class MachineRegistryController {
|
||||||
machineInfo.setIp(ip);
|
machineInfo.setIp(ip);
|
||||||
machineInfo.setPort(port);
|
machineInfo.setPort(port);
|
||||||
machineInfo.setHeartbeatVersion(version);
|
machineInfo.setHeartbeatVersion(version);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis());
|
machineInfo.setLastHeartbeat(System.currentTimeMillis());
|
||||||
machineInfo.setVersion(sentinelVersion);
|
machineInfo.setVersion(sentinelVersion);
|
||||||
appManagement.addMachine(machineInfo);
|
appManagement.addMachine(machineInfo);
|
||||||
return Result.ofSuccessMsg("success");
|
return Result.ofSuccessMsg("success");
|
||||||
|
|
|
||||||
|
|
@ -25,24 +25,25 @@ import com.alibaba.csp.sentinel.dashboard.domain.ResourceTreeNode;
|
||||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.vo.ResourceVo;
|
import com.alibaba.csp.sentinel.dashboard.domain.vo.ResourceVo;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author leyou
|
* @author Carpenter Lee
|
||||||
*/
|
*/
|
||||||
@Controller
|
@RestController
|
||||||
@RequestMapping(value = "/resource", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/resource")
|
||||||
public class ResourceController {
|
public class ResourceController {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(ResourceController.class);
|
private static Logger logger = LoggerFactory.getLogger(ResourceController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
SentinelApiClient httpFetcher;
|
private SentinelApiClient httpFetcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch real time statistics info of the machine.
|
* Fetch real time statistics info of the machine.
|
||||||
|
|
@ -54,9 +55,9 @@ public class ResourceController {
|
||||||
* @param searchKey key to search
|
* @param searchKey key to search
|
||||||
* @return node statistics info.
|
* @return node statistics info.
|
||||||
*/
|
*/
|
||||||
@ResponseBody
|
@GetMapping("/machineResource.json")
|
||||||
@RequestMapping("/machineResource.json")
|
public Result<List<ResourceVo>> fetchResourceChainListOfMachine(String ip, Integer port, String type,
|
||||||
Result<?> fetchIdentityOfMachine(String ip, Integer port, String type, String searchKey) {
|
String searchKey) {
|
||||||
if (StringUtil.isEmpty(ip) || port == null) {
|
if (StringUtil.isEmpty(ip) || port == null) {
|
||||||
return Result.ofFail(-1, "invalid param, give ip, port");
|
return Result.ofFail(-1, "invalid param, give ip, port");
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +74,8 @@ public class ResourceController {
|
||||||
ResourceTreeNode treeNode = ResourceTreeNode.fromNodeVoList(nodeVos);
|
ResourceTreeNode treeNode = ResourceTreeNode.fromNodeVoList(nodeVos);
|
||||||
treeNode.searchIgnoreCase(searchKey);
|
treeNode.searchIgnoreCase(searchKey);
|
||||||
return Result.ofSuccess(ResourceVo.fromResourceTreeNode(treeNode));
|
return Result.ofSuccess(ResourceVo.fromResourceTreeNode(treeNode));
|
||||||
} else {// cluster
|
} else {
|
||||||
|
// Normal (cluster node).
|
||||||
List<NodeVo> nodeVos = httpFetcher.fetchClusterNodeOfMachine(ip, port, true);
|
List<NodeVo> nodeVos = httpFetcher.fetchClusterNodeOfMachine(ip, port, true);
|
||||||
if (nodeVos == null) {
|
if (nodeVos == null) {
|
||||||
return Result.ofSuccess(null);
|
return Result.ofSuccess(null);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import com.alibaba.csp.sentinel.dashboard.discovery.AppInfo;
|
||||||
* @author leyou
|
* @author leyou
|
||||||
*/
|
*/
|
||||||
public class ApplicationEntity {
|
public class ApplicationEntity {
|
||||||
|
|
||||||
private Long id;
|
private Long id;
|
||||||
private Date gmtCreate;
|
private Date gmtCreate;
|
||||||
private Date gmtModified;
|
private Date gmtModified;
|
||||||
|
|
@ -79,10 +80,7 @@ public class ApplicationEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppInfo toAppInfo() {
|
public AppInfo toAppInfo() {
|
||||||
AppInfo appInfo = new AppInfo();
|
return new AppInfo(app);
|
||||||
appInfo.setApp(app);
|
|
||||||
|
|
||||||
return appInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ public class MachineEntity {
|
||||||
machineInfo.setHostname(hostname);
|
machineInfo.setHostname(hostname);
|
||||||
machineInfo.setIp(ip);
|
machineInfo.setIp(ip);
|
||||||
machineInfo.setPort(port);
|
machineInfo.setPort(port);
|
||||||
machineInfo.setLastHeatbeat(timestamp.getTime());
|
machineInfo.setLastHeartbeat(timestamp.getTime());
|
||||||
machineInfo.setHeartbeatVersion(timestamp.getTime());
|
machineInfo.setHeartbeatVersion(timestamp.getTime());
|
||||||
|
|
||||||
return machineInfo;
|
return machineInfo;
|
||||||
|
|
|
||||||
|
|
@ -25,26 +25,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import com.alibaba.csp.sentinel.dashboard.config.DashboardConfig;
|
import com.alibaba.csp.sentinel.dashboard.config.DashboardConfig;
|
||||||
|
|
||||||
public class AppInfo {
|
public class AppInfo {
|
||||||
private static final Comparator<MachineInfo> COMPARATOR_BY_MACHINE_HEARTBEAT_DESC = new Comparator<MachineInfo>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(MachineInfo o1, MachineInfo o2) {
|
|
||||||
if (o1.getLastHeatbeat() < o2.getLastHeatbeat()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (o1.getLastHeatbeat() > o2.getLastHeatbeat()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private String app = "";
|
private String app = "";
|
||||||
|
|
||||||
private Set<MachineInfo> machines = ConcurrentHashMap.newKeySet();
|
private Set<MachineInfo> machines = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
public AppInfo() {
|
public AppInfo() {}
|
||||||
}
|
|
||||||
|
|
||||||
public AppInfo(String app) {
|
public AppInfo(String app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
@ -95,37 +81,38 @@ public class AppInfo {
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean heartbeatJudge(int threshold) {
|
private boolean heartbeatJudge(final int threshold) {
|
||||||
if (machines.size() == 0) {
|
if (machines.size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (threshold > 0) {
|
if (threshold > 0) {
|
||||||
long healthyCount = machines.stream()
|
long healthyCount = machines.stream()
|
||||||
.filter(m -> m.isHealthy())
|
.filter(MachineInfo::isHealthy)
|
||||||
.count();
|
.count();
|
||||||
if (healthyCount == 0) {
|
if (healthyCount == 0) {
|
||||||
// no machine
|
// No healthy machines.
|
||||||
long recentHeartBeat = machines.stream()
|
return machines.stream()
|
||||||
.max(COMPARATOR_BY_MACHINE_HEARTBEAT_DESC).get().getLastHeatbeat();
|
.max(Comparator.comparingLong(MachineInfo::getLastHeartbeat))
|
||||||
return System.currentTimeMillis() - recentHeartBeat < threshold;
|
.map(e -> System.currentTimeMillis() - e.getLastHeartbeat() < threshold)
|
||||||
|
.orElse(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* having no healthy machine and should not be displayed
|
* Check whether current application has no healthy machines and should not be displayed.
|
||||||
*
|
*
|
||||||
* @return
|
* @return true if the application should be displayed in the sidebar, otherwise false
|
||||||
*/
|
*/
|
||||||
public boolean isShown() {
|
public boolean isShown() {
|
||||||
return heartbeatJudge(DashboardConfig.getHideAppNoMachineMillis());
|
return heartbeatJudge(DashboardConfig.getHideAppNoMachineMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* having no healthy machine and should be removed
|
* Check whether current application has no healthy machines and should be removed.
|
||||||
*
|
*
|
||||||
* @return
|
* @return true if the application is dead and should be removed, otherwise false
|
||||||
*/
|
*/
|
||||||
public boolean isDead() {
|
public boolean isDead() {
|
||||||
return !heartbeatJudge(DashboardConfig.getRemoveAppNoMachineMillis());
|
return !heartbeatJudge(DashboardConfig.getRemoveAppNoMachineMillis());
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,10 @@ import org.springframework.stereotype.Component;
|
||||||
@Component
|
@Component
|
||||||
public class AppManagement implements MachineDiscovery {
|
public class AppManagement implements MachineDiscovery {
|
||||||
|
|
||||||
//@Value("${appmanagement.maxnode}")
|
|
||||||
//private Integer maxNode;
|
|
||||||
//
|
|
||||||
//@Value("${discovery.type}")
|
|
||||||
//private String type;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext context;
|
private ApplicationContext context;
|
||||||
|
|
||||||
MachineDiscovery machineDiscovery;
|
private MachineDiscovery machineDiscovery;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,24 @@ public interface MachineDiscovery {
|
||||||
|
|
||||||
AppInfo getDetailApp(String app);
|
AppInfo getDetailApp(String app);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given app from the application registry.
|
||||||
|
*
|
||||||
|
* @param app application name
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
void removeApp(String app);
|
void removeApp(String app);
|
||||||
|
|
||||||
long addMachine(MachineInfo machineInfo);
|
long addMachine(MachineInfo machineInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given machine instance from the application registry.
|
||||||
|
*
|
||||||
|
* @param app the application name of the machine
|
||||||
|
* @param ip machine IP
|
||||||
|
* @param port machine port
|
||||||
|
* @return true if removed, otherwise false
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
boolean removeMachine(String app, String ip, int port);
|
boolean removeMachine(String app, String ip, int port);
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ public class MachineInfo implements Comparable<MachineInfo> {
|
||||||
private String hostname = "";
|
private String hostname = "";
|
||||||
private String ip = "";
|
private String ip = "";
|
||||||
private Integer port = -1;
|
private Integer port = -1;
|
||||||
private long lastHeatbeat;
|
private long lastHeartbeat;
|
||||||
private long heartbeatVersion;
|
private long heartbeatVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,7 +96,7 @@ public class MachineInfo implements Comparable<MachineInfo> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHealthy() {
|
public boolean isHealthy() {
|
||||||
long delta = System.currentTimeMillis() - lastHeatbeat;
|
long delta = System.currentTimeMillis() - lastHeartbeat;
|
||||||
return delta < DashboardConfig.getUnhealthyMachineMillis();
|
return delta < DashboardConfig.getUnhealthyMachineMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,18 +107,18 @@ public class MachineInfo implements Comparable<MachineInfo> {
|
||||||
*/
|
*/
|
||||||
public boolean isDead() {
|
public boolean isDead() {
|
||||||
if (DashboardConfig.getAutoRemoveMachineMillis() > 0) {
|
if (DashboardConfig.getAutoRemoveMachineMillis() > 0) {
|
||||||
long delta = System.currentTimeMillis() - lastHeatbeat;
|
long delta = System.currentTimeMillis() - lastHeartbeat;
|
||||||
return delta > DashboardConfig.getAutoRemoveMachineMillis();
|
return delta > DashboardConfig.getAutoRemoveMachineMillis();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastHeatbeat() {
|
public long getLastHeartbeat() {
|
||||||
return lastHeatbeat;
|
return lastHeartbeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastHeatbeat(long lastHeatbeat) {
|
public void setLastHeartbeat(long lastHeartbeat) {
|
||||||
this.lastHeatbeat = lastHeatbeat;
|
this.lastHeartbeat = lastHeartbeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -143,7 +143,7 @@ public class MachineInfo implements Comparable<MachineInfo> {
|
||||||
.append(", ip='").append(ip).append('\'')
|
.append(", ip='").append(ip).append('\'')
|
||||||
.append(", port=").append(port)
|
.append(", port=").append(port)
|
||||||
.append(", heartbeatVersion=").append(heartbeatVersion)
|
.append(", heartbeatVersion=").append(heartbeatVersion)
|
||||||
.append(", lastHeartbeat=").append(lastHeatbeat)
|
.append(", lastHeartbeat=").append(lastHeartbeat)
|
||||||
.append(", version='").append(version).append('\'')
|
.append(", version='").append(version).append('\'')
|
||||||
.append(", healthy=").append(isHealthy())
|
.append(", healthy=").append(isHealthy())
|
||||||
.append('}').toString();
|
.append('}').toString();
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
@ -28,17 +31,20 @@ import org.springframework.stereotype.Component;
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class SimpleMachineDiscovery implements MachineDiscovery {
|
public class SimpleMachineDiscovery implements MachineDiscovery {
|
||||||
protected ConcurrentHashMap<String, AppInfo> apps = new ConcurrentHashMap<>();
|
|
||||||
|
private final ConcurrentMap<String, AppInfo> apps = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long addMachine(MachineInfo machineInfo) {
|
public long addMachine(MachineInfo machineInfo) {
|
||||||
AppInfo appInfo = apps.computeIfAbsent(machineInfo.getApp(), app -> new AppInfo(app));
|
AssertUtil.notNull(machineInfo, "machineInfo cannot be null");
|
||||||
|
AppInfo appInfo = apps.computeIfAbsent(machineInfo.getApp(), AppInfo::new);
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeMachine(String app, String ip, int port) {
|
public boolean removeMachine(String app, String ip, int port) {
|
||||||
|
AssertUtil.assertNotBlank(app, "app name cannot be blank");
|
||||||
AppInfo appInfo = apps.get(app);
|
AppInfo appInfo = apps.get(app);
|
||||||
if (appInfo != null) {
|
if (appInfo != null) {
|
||||||
return appInfo.removeMachine(ip, port);
|
return appInfo.removeMachine(ip, port);
|
||||||
|
|
@ -53,6 +59,7 @@ public class SimpleMachineDiscovery implements MachineDiscovery {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppInfo getDetailApp(String app) {
|
public AppInfo getDetailApp(String app) {
|
||||||
|
AssertUtil.assertNotBlank(app, "app name cannot be blank");
|
||||||
return apps.get(app);
|
return apps.get(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,6 +70,7 @@ public class SimpleMachineDiscovery implements MachineDiscovery {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeApp(String app) {
|
public void removeApp(String app) {
|
||||||
|
AssertUtil.assertNotBlank(app, "app name cannot be blank");
|
||||||
apps.remove(app);
|
apps.remove(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public class MachineInfoVo {
|
||||||
vo.setHostname(machine.getHostname());
|
vo.setHostname(machine.getHostname());
|
||||||
vo.setIp(machine.getIp());
|
vo.setIp(machine.getIp());
|
||||||
vo.setPort(machine.getPort());
|
vo.setPort(machine.getPort());
|
||||||
vo.setLastHeartbeat(machine.getLastHeatbeat());
|
vo.setLastHeartbeat(machine.getLastHeartbeat());
|
||||||
vo.setHeartbeatVersion(machine.getHeartbeatVersion());
|
vo.setHeartbeatVersion(machine.getHeartbeatVersion());
|
||||||
vo.setVersion(machine.getVersion());
|
vo.setVersion(machine.getVersion());
|
||||||
vo.setHealthy(machine.isHealthy());
|
vo.setHealthy(machine.isHealthy());
|
||||||
|
|
|
||||||
|
|
@ -47,16 +47,8 @@ public class FlowRuleApiProvider implements DynamicRuleProvider<List<FlowRuleEnt
|
||||||
}
|
}
|
||||||
List<MachineInfo> list = appManagement.getDetailApp(appName).getMachines()
|
List<MachineInfo> list = appManagement.getDetailApp(appName).getMachines()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(e -> e.isHealthy())
|
.filter(MachineInfo::isHealthy)
|
||||||
.sorted((e1, e2) -> {
|
.sorted((e1, e2) -> Long.compare(e2.getLastHeartbeat(), e1.getLastHeartbeat())).collect(Collectors.toList());
|
||||||
if (e1.getLastHeatbeat() < e2.getLastHeatbeat()) {
|
|
||||||
return 1;
|
|
||||||
} else if (e1.getLastHeatbeat() > e2.getLastHeatbeat()) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import com.alibaba.csp.sentinel.util.function.Tuple2;
|
||||||
* @author Eric Zhao
|
* @author Eric Zhao
|
||||||
*/
|
*/
|
||||||
public final class MachineUtils {
|
public final class MachineUtils {
|
||||||
|
|
||||||
public static Optional<Integer> parseCommandPort(String machineIp) {
|
public static Optional<Integer> parseCommandPort(String machineIp) {
|
||||||
try {
|
try {
|
||||||
if (!machineIp.contains("@")) {
|
if (!machineIp.contains("@")) {
|
||||||
|
|
@ -53,4 +54,6 @@ public final class MachineUtils {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MachineUtils() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ angular.module('sentinelDashboardApp').controller('AuthorityRuleController', ['$
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ app.controller('SentinelClusterSingleController', ['$scope', '$stateParams', 'ng
|
||||||
$scope.macsInputOptionsOrigin = [];
|
$scope.macsInputOptionsOrigin = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptionsOrigin.push({
|
$scope.macsInputOptionsOrigin.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', '
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ app.controller('FlowControllerV2', ['$scope', '$stateParams', 'FlowServiceV2', '
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -387,13 +387,12 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService',
|
||||||
function queryAppMachines() {
|
function queryAppMachines() {
|
||||||
MachineService.getAppMachines($scope.app).success(
|
MachineService.getAppMachines($scope.app).success(
|
||||||
function (data) {
|
function (data) {
|
||||||
if (data.code == 0) {
|
if (data.code === 0) {
|
||||||
// $scope.machines = data.data;
|
|
||||||
if (data.data) {
|
if (data.data) {
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@ angular.module('sentinelDashboardApp').controller('ParamFlowController', ['$scop
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ app.controller('SystemCtl', ['$scope', '$stateParams', 'SystemService', 'ngDialo
|
||||||
$scope.machines = [];
|
$scope.machines = [];
|
||||||
$scope.macsInputOptions = [];
|
$scope.macsInputOptions = [];
|
||||||
data.data.forEach(function (item) {
|
data.data.forEach(function (item) {
|
||||||
if (item.health) {
|
if (item.healthy) {
|
||||||
$scope.macsInputOptions.push({
|
$scope.macsInputOptions.push({
|
||||||
text: item.ip + ':' + item.port,
|
text: item.ip + ':' + item.port,
|
||||||
value: item.ip + ':' + item.port
|
value: item.ip + ':' + item.port
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public class AppInfoTest {
|
||||||
machineInfo.setHostname("bogon");
|
machineInfo.setHostname("bogon");
|
||||||
machineInfo.setIp("127.0.0.1");
|
machineInfo.setIp("127.0.0.1");
|
||||||
machineInfo.setPort(3389);
|
machineInfo.setPort(3389);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis());
|
machineInfo.setLastHeartbeat(System.currentTimeMillis());
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setVersion("0.4.1");
|
machineInfo.setVersion("0.4.1");
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
|
|
@ -92,7 +92,7 @@ public class AppInfoTest {
|
||||||
machineInfo.setHostname("bogon");
|
machineInfo.setHostname("bogon");
|
||||||
machineInfo.setIp("127.0.0.1");
|
machineInfo.setIp("127.0.0.1");
|
||||||
machineInfo.setPort(3389);
|
machineInfo.setPort(3389);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis());
|
machineInfo.setLastHeartbeat(System.currentTimeMillis());
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setVersion("0.4.2");
|
machineInfo.setVersion("0.4.2");
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
|
|
@ -105,7 +105,7 @@ public class AppInfoTest {
|
||||||
machineInfo.setHostname("bogon");
|
machineInfo.setHostname("bogon");
|
||||||
machineInfo.setIp("127.0.0.1");
|
machineInfo.setIp("127.0.0.1");
|
||||||
machineInfo.setPort(3390);
|
machineInfo.setPort(3390);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis());
|
machineInfo.setLastHeartbeat(System.currentTimeMillis());
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setVersion("0.4.3");
|
machineInfo.setVersion("0.4.3");
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
|
|
@ -128,7 +128,7 @@ public class AppInfoTest {
|
||||||
{
|
{
|
||||||
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
|
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis());
|
machineInfo.setLastHeartbeat(System.currentTimeMillis());
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
}
|
}
|
||||||
assertTrue(appInfo.isShown());
|
assertTrue(appInfo.isShown());
|
||||||
|
|
@ -137,7 +137,7 @@ public class AppInfoTest {
|
||||||
{
|
{
|
||||||
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
|
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 70000);
|
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 70000);
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
}
|
}
|
||||||
assertFalse(appInfo.isShown());
|
assertFalse(appInfo.isShown());
|
||||||
|
|
@ -146,7 +146,7 @@ public class AppInfoTest {
|
||||||
{
|
{
|
||||||
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
|
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 700000);
|
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 700000);
|
||||||
appInfo.addMachine(machineInfo);
|
appInfo.addMachine(machineInfo);
|
||||||
}
|
}
|
||||||
assertFalse(appInfo.isShown());
|
assertFalse(appInfo.isShown());
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,11 @@ import org.junit.Test;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.config.DashboardConfig;
|
import com.alibaba.csp.sentinel.dashboard.config.DashboardConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jason Joo
|
||||||
|
*/
|
||||||
public class MachineInfoTest {
|
public class MachineInfoTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHealthyAndDead() {
|
public void testHealthyAndDead() {
|
||||||
System.setProperty(DashboardConfig.CONFIG_UNHEALTHY_MACHINE_MILLIS, "60000");
|
System.setProperty(DashboardConfig.CONFIG_UNHEALTHY_MACHINE_MILLIS, "60000");
|
||||||
|
|
@ -29,15 +33,15 @@ public class MachineInfoTest {
|
||||||
DashboardConfig.clearCache();
|
DashboardConfig.clearCache();
|
||||||
MachineInfo machineInfo = new MachineInfo();
|
MachineInfo machineInfo = new MachineInfo();
|
||||||
machineInfo.setHeartbeatVersion(1);
|
machineInfo.setHeartbeatVersion(1);
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 10000);
|
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 10000);
|
||||||
assertTrue(machineInfo.isHealthy());
|
assertTrue(machineInfo.isHealthy());
|
||||||
assertFalse(machineInfo.isDead());
|
assertFalse(machineInfo.isDead());
|
||||||
|
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 100000);
|
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 100000);
|
||||||
assertFalse(machineInfo.isHealthy());
|
assertFalse(machineInfo.isHealthy());
|
||||||
assertFalse(machineInfo.isDead());
|
assertFalse(machineInfo.isDead());
|
||||||
|
|
||||||
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 1000000);
|
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 1000000);
|
||||||
assertFalse(machineInfo.isHealthy());
|
assertFalse(machineInfo.isHealthy());
|
||||||
assertTrue(machineInfo.isDead());
|
assertTrue(machineInfo.isDead());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,13 +119,11 @@ public class InMemoryMetricsRepositoryTest {
|
||||||
try {
|
try {
|
||||||
cyclicBarrier.await();
|
cyclicBarrier.await();
|
||||||
inMemoryMetricsRepository.listResourcesOfApp(DEFAULT_APP);
|
inMemoryMetricsRepository.listResourcesOfApp(DEFAULT_APP);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException | BrokenBarrierException e) {
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BrokenBarrierException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}, executorService
|
}, executorService)
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// batch add metric entity
|
// batch add metric entity
|
||||||
|
|
@ -142,11 +140,20 @@ public class InMemoryMetricsRepositoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
CompletableFuture all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
all.join();
|
all.get(10, TimeUnit.SECONDS);
|
||||||
} catch (ConcurrentModificationException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
e.getCause().printStackTrace();
|
||||||
|
if (e.getCause() instanceof ConcurrentModificationException) {
|
||||||
fail("concurrent error occurred");
|
fail("concurrent error occurred");
|
||||||
|
} else {
|
||||||
|
fail("unexpected exception");
|
||||||
|
}
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
fail("allOf future timeout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ import java.util.List;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
||||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.nacos.api.config.ConfigFactory;
|
|
||||||
import com.alibaba.nacos.api.config.ConfigService;
|
|
||||||
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
|
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,12 @@ import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
|
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
|
||||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
|
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
|
||||||
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
|
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
|
||||||
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
|
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
|
||||||
|
|
@ -57,6 +59,5 @@ public class FlowRuleApolloProvider implements DynamicRuleProvider<List<FlowRule
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
return converter.convert(rules);
|
return converter.convert(rules);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,12 @@ import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
|
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
|
||||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||||
import com.alibaba.nacos.api.config.ConfigService;
|
|
||||||
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
|
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
|
||||||
import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
|
import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
|
||||||
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
|
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
|
||||||
|
|
@ -47,27 +48,22 @@ public class FlowRuleApolloPublisher implements DynamicRulePublisher<List<FlowRu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Increase the configuration
|
||||||
* Increase the configuration
|
|
||||||
*/
|
|
||||||
String appId = "appId";
|
String appId = "appId";
|
||||||
String flowDataId = ApolloConfigUtil.getFlowDataId(app);
|
String flowDataId = ApolloConfigUtil.getFlowDataId(app);
|
||||||
OpenItemDTO openItemDTO = new OpenItemDTO();
|
OpenItemDTO openItemDTO = new OpenItemDTO();
|
||||||
openItemDTO.setKey(flowDataId);
|
openItemDTO.setKey(flowDataId);
|
||||||
openItemDTO.setValue(converter.convert(rules));
|
openItemDTO.setValue(converter.convert(rules));
|
||||||
openItemDTO.setComment("Program auto-join");
|
openItemDTO.setComment("Program auto-join");
|
||||||
openItemDTO.setDataChangeCreatedBy("hantianwei");
|
openItemDTO.setDataChangeCreatedBy("some-operator");
|
||||||
apolloOpenApiClient.createOrUpdateItem(appId, "DEV", "default", "application", openItemDTO);
|
apolloOpenApiClient.createOrUpdateItem(appId, "DEV", "default", "application", openItemDTO);
|
||||||
|
|
||||||
/**
|
// Release configuration
|
||||||
* Release configuration
|
|
||||||
*/
|
|
||||||
NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
|
NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
|
||||||
namespaceReleaseDTO.setEmergencyPublish(true);
|
namespaceReleaseDTO.setEmergencyPublish(true);
|
||||||
namespaceReleaseDTO.setReleaseComment("Modify or add configurations");
|
namespaceReleaseDTO.setReleaseComment("Modify or add configurations");
|
||||||
namespaceReleaseDTO.setReleasedBy("hantianwei");
|
namespaceReleaseDTO.setReleasedBy("some-operator");
|
||||||
namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");
|
namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");
|
||||||
apolloOpenApiClient.publishNamespace(appId, "DEV", "default", "application", namespaceReleaseDTO);
|
apolloOpenApiClient.publishNamespace(appId, "DEV", "default", "application", namespaceReleaseDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue