Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/noear/solon into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
noear committed Jul 25, 2023
2 parents 997c804 + 1d3c0a1 commit 017c4b1
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 16 deletions.
53 changes: 53 additions & 0 deletions solon-projects/solon-tool/solon-admin-client/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Solon Admin Client

```xml

<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-admin-client</artifactId>
</dependency>
```

## 1. 描述

**需配合 Solon Admin Server 一起使用**

Solon Admin 是一款基于 Solon 的轻量级应用监视器,可用于监视 Solon 应用的运行状态。

## 2. 使用

引入包后,启动类添加注解:`@EnableAdminServer`

```java

@EnableAdminClient
@SolonMain
public class Main {

public static void main(String[] args) {
Solon.start(Main.class, args);
}
}
```

之后启动应用程序,访问 Solon Admin Server 实例的地址即可使用。

## 3. 配置

```yaml
solon.admin.client:
enabled: true #是否启用 Solon Admin Client
mode: "local" #模式:local 本地模式,cloud 云模式
serverUrl: "http://localhost:8080" #Solon Admin Server 实例地址
connectTimeout: 5000 #连接超时,单位:毫秒
readTimeout: 5000 #读取超时,单位:毫秒
metadata: "" #自定义元数据
showSecretInformation: false #是否向服务端发送敏感信息,如环境变量等

## 设置 Solon Health Detector 监视器,* 为启用全部监视器
solon.health.detector: "*"
```
## 4. 配置中心
Solon Admin Client 支持连接到配置中心,只需将 `mode` 设置为 `cloud`,并在 Solon 中配置配置中心相关信息即可启用。
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class CloudClientProperties implements IClientProperties {

private String mode = "cloud";

private String serverUrl;
private String serverUrl = "http://localhost:8080";

private long heartbeatInterval = 10 * 1000;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class LocalClientProperties implements IClientProperties {

private String mode = "local";

private String serverUrl;
private String serverUrl = "http://localhost:8080";

private long heartbeatInterval = 10 * 1000;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class Application extends UniqueApplication {
lastDownTime: number
showSecretInformation: boolean
environmentInformation: EnvironmentInformation
monitors: (JVMDetector | DiskDetector | CPUDetector | OSDetector | MemoryDetector | Detector)[]
monitors?: (JVMDetector | DiskDetector | CPUDetector | OSDetector | MemoryDetector | Detector)[]

constructor(name: string, baseUrl: string, metadata: string | undefined, status: ApplicationStatus, lastHeartbeat: number, startupTime: number, lastUpTime: number, lastDownTime: number, showSecretInformation: boolean, environmentInformation: EnvironmentInformation, monitors: Detector[]) {
super(name, baseUrl);
Expand Down Expand Up @@ -119,4 +119,4 @@ export type JVMDetector = {
usable: string,
free: string
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ onMounted(() => {
<a-empty v-else/>
</a-card>
</div>
<div v-for="monitor in application?.monitors.sort((a,b)=>a.name.charCodeAt(0)-b.name.charCodeAt(0))"
<div v-for="monitor in application?.monitors?.sort((a,b)=>a.name.charCodeAt(0)-b.name.charCodeAt(0))"
:key="monitor.name">
<a-card :title="t(`application.details.dashboard.${monitor.name}.title`)" class="card">
<template v-if="monitor.name==='memory'">
Expand Down Expand Up @@ -369,4 +369,4 @@ onMounted(() => {
height: 400px;
width: 400px;
}
</style>
</style>
47 changes: 47 additions & 0 deletions solon-projects/solon-tool/solon-admin-server/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Solon Admin Server

```xml
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-admin-server</artifactId>
</dependency>
```

## 1. 描述

**需配合 Solon Admin Client 一起使用**

Solon Admin 是一款基于 Solon 的轻量级应用监视器,可用于监视 Solon 应用的运行状态。

## 2. 使用

引入包后,启动类添加注解:`@EnableAdminServer`

```java
@EnableAdminServer
@SolonMain
public class Main {

public static void main(String[] args) {
Solon.start(Main.class, args);
}
}
```

之后启动应用程序,访问 `http://localhost:8080`(默认地址)即可查看相关信息。

## 3. 配置

```yaml
solon.admin.server:
enabled: true #是否启用 Solon Admin Server
mode: "local" #模式:local 本地模式,cloud 云模式
heartbeatInterval: 10000 #心跳速率,单位:毫秒
clientMonitorPeriod: 2000 #客户端监控周期,单位:毫秒
connectTimeout: 5000 #连接超时,单位:毫秒
readTimeout: 5000 #读取超时,单位:毫秒
```
## 4. 配置中心
Solon Admin Server 支持连接到配置中心,只需将 `mode` 设置为 `cloud`,并在 Solon 中配置配置中心相关信息即可启用。
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;

@Inject("${solon.admin.server}")
@Inject(value = "${solon.admin.server}", required = false)
@Configuration
@Data
public class ServerProperties {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,24 @@ public class Application {
@EqualsAndHashCode.Exclude
private Collection<Detector> monitors;

public void replace(Application application) {
this.metadata = application.metadata;
this.status = application.status;
this.startupTime = application.startupTime;
this.lastHeartbeat = application.lastHeartbeat;
this.lastUpTime = application.lastUpTime;
this.lastDownTime = application.lastDownTime;
this.showSecretInformation = application.showSecretInformation;
this.environmentInformation = application.environmentInformation;
this.monitors = application.monitors;
}

public enum Status {
UP,
DOWN
}

public String toKey() {
return name + "@" + baseUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@Component
public class ApplicationService {

private final Set<Application> applications = new HashSet<>();
private final Map<String, Application> applications = new HashMap<>();

private final Map<Application, Runnable> runningHeartbeatTasks = new HashMap<>();

Expand All @@ -37,9 +37,14 @@ public class ApplicationService {
private ClientMonitorService clientMonitorService;

public void registerApplication(Application application) {
if (applications.contains(application)) return;
String key = application.toKey();
Application persisted = applications.get(key);
if (persisted != null) { // on app restart, update app info
persisted.replace(application);
return;
}

applications.add(application);
applications.put(key, application);
scheduleHeartbeatCheck(application);
sessions.forEach(it -> it.sendAsync(JsonUtils.toJson(new ApplicationWebsocketTransfer<>(
null,
Expand All @@ -53,10 +58,10 @@ public void registerApplication(Application application) {
}

public void unregisterApplication(Application application) {
val find = applications.stream().filter(it -> it.equals(application)).findFirst();
val find = applications.values().stream().filter(it -> it.equals(application)).findFirst();
if (!find.isPresent()) return;

applications.remove(find.get());
applications.remove(find.get().toKey());
scheduledThreadPoolExecutor.remove(runningHeartbeatTasks.get(find.get()));
scheduledThreadPoolExecutor.remove(runningClientMonitorTasks.get(find.get()));
sessions.forEach(it -> it.sendAsync(JsonUtils.toJson(new ApplicationWebsocketTransfer<>(
Expand All @@ -69,7 +74,7 @@ public void unregisterApplication(Application application) {
}

public void heartbeatApplication(Application application) {
val find = applications.stream().filter(it -> it.equals(application)).findFirst();
val find = applications.values().stream().filter(it -> it.equals(application)).findFirst();
if (!find.isPresent()) return;
find.get().setLastHeartbeat(System.currentTimeMillis());

Expand Down Expand Up @@ -133,12 +138,12 @@ private void runClientMonitor(Application application) {
))));
}

public Set<Application> getApplications() {
return new HashSet<>(applications);
public Collection<Application> getApplications() {
return applications.values();
}

public Application getApplication(String name, String baseUrl) {
val find = applications.stream().filter(it -> it.getName().equals(name) && it.getBaseUrl().equals(baseUrl)).findFirst();
val find = applications.values().stream().filter(it -> it.getName().equals(name) && it.getBaseUrl().equals(baseUrl)).findFirst();
return find.orElse(null);
}

Expand Down

0 comments on commit 017c4b1

Please sign in to comment.