refactor: 优化配置
This commit is contained in:
parent
3be58dce1e
commit
f194946492
|
|
@ -1,20 +1,25 @@
|
|||
version: '2'
|
||||
version: '3'
|
||||
services:
|
||||
redis:
|
||||
image: redis:6
|
||||
container_name: jetlinks-ce-redis
|
||||
# ports:
|
||||
# - "6379:6379"
|
||||
# - "6379:6379" # 仅供jetlinks-ce访问
|
||||
volumes:
|
||||
- "./data/redis:/data"
|
||||
command: redis-server --appendonly yes --requirepass "JetLinks@redis"
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-h", "localhost", "-p", "6379", "-a", "JetLinks@redis", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
postgres:
|
||||
image: timescale/timescaledb:latest-pg16
|
||||
container_name: jetlinks-postgres-16
|
||||
ports:
|
||||
- "5432:5432"
|
||||
container_name: jetlinks-ce-postgres
|
||||
# ports:
|
||||
# - "5432:5432" # 仅供jetlinks-ce访问
|
||||
volumes:
|
||||
- "./data/postgres:/var/lib/postgresql/data"
|
||||
environment:
|
||||
|
|
@ -22,6 +27,11 @@ services:
|
|||
POSTGRES_DB: jetlinks
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
TZ: Asia/Shanghai
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "postgres"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
jetlinks:
|
||||
image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-community:2.10.0-SNAPSHOT
|
||||
container_name: jetlinks-ce
|
||||
|
|
@ -31,19 +41,18 @@ services:
|
|||
- "8800-8810:8800-8810" # 预留
|
||||
- "5060-5061:5060-5061" # 预留
|
||||
volumes:
|
||||
- "./data/jetlinks/upload:/application/static/upload"
|
||||
- "./data/jetlinks:/application/data"
|
||||
environment:
|
||||
- "JAVA_OPTS=-Duser.language=zh"
|
||||
- "TZ=Asia/Shanghai"
|
||||
- "hsweb.file.upload.static-location=http://127.0.0.1:8848/upload" #上传的静态文件访问根地址,为ui的地址.
|
||||
- "ADMIN_USER_PASSWORD=JetLinks.C0mmVn1ty" # admin用户的初始密码
|
||||
- "spring.r2dbc.url=r2dbc:postgresql://postgres:5432/jetlinks" #数据库连接地址
|
||||
- "spring.r2dbc.username=postgres"
|
||||
- "spring.r2dbc.password=JetLinks@postgres"
|
||||
- "spring.data.redis.host=redis"
|
||||
- "spring.data.redis.port=6379"
|
||||
- "file.manager.storage-base-path=/application/data/files"
|
||||
- "spring.redis.password=JetLinks@redis"
|
||||
- "spring.data.redis.password=JetLinks@redis"
|
||||
- "logging.level.io.r2dbc=warn"
|
||||
- "logging.level.org.springframework.data=warn"
|
||||
- "logging.level.org.springframework=warn"
|
||||
|
|
@ -67,5 +76,7 @@ services:
|
|||
- redis:redis
|
||||
- postgres:postgres
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import org.hswebframework.web.authorization.exception.UnAuthorizedException;
|
|||
import org.jetlinks.community.resource.Resource;
|
||||
import org.jetlinks.community.resource.ResourceManager;
|
||||
import org.jetlinks.community.resource.TypeScriptDeclareResourceProvider;
|
||||
import org.jetlinks.community.resource.ui.UiResourceProvider;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
|
@ -17,6 +18,7 @@ import reactor.core.publisher.Flux;
|
|||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/system/resources")
|
||||
|
|
@ -26,6 +28,15 @@ public class SystemResourcesController {
|
|||
|
||||
private final ResourceManager resourceManager;
|
||||
|
||||
@GetMapping("/ui")
|
||||
@SneakyThrows
|
||||
@Authorize(merge = false)
|
||||
public Flux<Object> getUIResources() {
|
||||
return resourceManager
|
||||
.getResources(UiResourceProvider.TYPE)
|
||||
.map(resource->resource.as(HashMap.class));
|
||||
}
|
||||
|
||||
@GetMapping("/{type}")
|
||||
@SneakyThrows
|
||||
public Flux<String> getResources(@PathVariable String type) {
|
||||
|
|
|
|||
|
|
@ -33,4 +33,11 @@ public class CpuInfo implements MonitorInfo<CpuInfo> {
|
|||
);
|
||||
}
|
||||
|
||||
public CpuInfo max(CpuInfo cpu) {
|
||||
return new CpuInfo(
|
||||
Math.max(this.jvmUsage, cpu.jvmUsage),
|
||||
Math.max(this.systemUsage, cpu.systemUsage)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.jetlinks.community.dashboard.measurements.sys;
|
|||
import com.google.common.collect.Maps;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
|
||||
import org.hswebframework.web.bean.FastBeanCopier;
|
||||
import org.jetlinks.community.dashboard.*;
|
||||
|
|
@ -113,6 +114,7 @@ import java.util.Map;
|
|||
* @since 2.0
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SystemMonitorMeasurementProvider extends StaticMeasurementProvider {
|
||||
|
||||
private static final String SYSTEM_MONITOR_REAL_TIME_TOPIC = "/_sys/monitor/info";
|
||||
|
|
@ -161,17 +163,39 @@ public class SystemMonitorMeasurementProvider extends StaticMeasurementProvider
|
|||
.block(Duration.ofSeconds(10));
|
||||
|
||||
//定时收集监控信息
|
||||
disposable.add(Flux
|
||||
.interval(collectInterval, scheduler)
|
||||
.flatMap(ignore -> monitorService
|
||||
.system()
|
||||
.map(this::systemInfoToMap)
|
||||
.flatMap(data -> timeSeriesManager
|
||||
.getService(metric)
|
||||
.commit(data)
|
||||
.then(eventBus.publish(SYSTEM_MONITOR_REAL_TIME_TOPIC,data)))
|
||||
.onErrorResume(err -> Mono.empty()))
|
||||
.subscribe()
|
||||
//定时收集监控信息
|
||||
disposable.add(
|
||||
Flux
|
||||
.interval(Duration.ofSeconds(1), scheduler)
|
||||
.onBackpressureDrop()
|
||||
//每秒采集一次
|
||||
.concatMap(l -> monitorService.cpu())
|
||||
//收集每个窗口的结果
|
||||
.window(collectInterval)
|
||||
.onBackpressureDrop(dropped -> log.warn("system monitor collect data dropped"))
|
||||
.concatMap(window -> Mono
|
||||
.zip(
|
||||
window
|
||||
.window(5)
|
||||
//5秒cpu平均值
|
||||
.flatMap(flx -> flx
|
||||
.reduce(CpuInfo::add)
|
||||
.map(cpu -> cpu.division(5)))
|
||||
//记录1分钟内最大平均值
|
||||
.reduce(CpuInfo::max),
|
||||
monitorService.memory(),
|
||||
monitorService.disk()
|
||||
)
|
||||
.map(tp3 -> this.systemInfoToMap(tp3.getT1(), tp3.getT2(), tp3.getT3()))
|
||||
.flatMap(timeSeriesManager.getService(metric)::commit)
|
||||
.onErrorResume(err -> {
|
||||
log.warn("collect system monitor data error", err);
|
||||
return Mono.empty();
|
||||
}), 1
|
||||
)
|
||||
.subscribe(null, error -> {
|
||||
log.warn("start system monitor task failed", error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -184,11 +208,11 @@ public class SystemMonitorMeasurementProvider extends StaticMeasurementProvider
|
|||
});
|
||||
}
|
||||
|
||||
public TimeSeriesData systemInfoToMap(SystemInfo info) {
|
||||
public TimeSeriesData systemInfoToMap(CpuInfo cpu, MemoryInfo memory, DiskInfo disk) {
|
||||
Map<String, Object> map = Maps.newLinkedHashMapWithExpectedSize(12);
|
||||
putTo("cpu", info.getCpu(), map);
|
||||
putTo("disk", info.getDisk(), map);
|
||||
putTo("memory", info.getMemory(), map);
|
||||
putTo("cpu", cpu, map);
|
||||
putTo("disk", disk, map);
|
||||
putTo("memory", memory, map);
|
||||
return TimeSeriesData.of(System.currentTimeMillis(), map);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity;
|
|||
import org.hswebframework.web.api.crud.entity.RecordCreationEntity;
|
||||
import org.hswebframework.web.crud.annotation.EnableEntityEvent;
|
||||
import org.hswebframework.web.crud.generator.Generators;
|
||||
import org.hswebframework.web.i18n.MultipleI18nSupportEntity;
|
||||
import org.hswebframework.web.utils.DigestUtils;
|
||||
import org.hswebframework.web.validator.CreateGroup;
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ import java.util.stream.Collectors;
|
|||
@Comment("菜单信息表")
|
||||
@EnableEntityEvent
|
||||
public class MenuEntity
|
||||
extends GenericTreeSortSupportEntity<String> implements RecordCreationEntity {
|
||||
extends GenericTreeSortSupportEntity<String> implements RecordCreationEntity, MultipleI18nSupportEntity {
|
||||
|
||||
/**
|
||||
* 在多应用集成运行时使用此字段来区分菜单属于哪个系统
|
||||
|
|
@ -123,6 +124,17 @@ public class MenuEntity
|
|||
)
|
||||
private Long createTime;
|
||||
|
||||
@Schema(title = "国际化信息定义")
|
||||
@Column
|
||||
@JsonCodec
|
||||
@ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class)
|
||||
private Map<String, Map<String, String>> i18nMessages;
|
||||
|
||||
|
||||
public String getI18nName() {
|
||||
return getI18nMessage("name", name);
|
||||
}
|
||||
|
||||
public boolean isSupportDataAccess() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
package org.jetlinks.community.auth.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.hswebframework.web.api.crud.entity.EntityFactoryHolder;
|
||||
import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity;
|
||||
import org.hswebframework.web.bean.FastBeanCopier;
|
||||
import org.hswebframework.web.i18n.MultipleI18nSupportEntity;
|
||||
import org.hswebframework.web.i18n.SingleI18nSupportEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
|
@ -17,8 +18,12 @@ import java.util.stream.Collectors;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MenuView extends GenericTreeSortSupportEntity<String> {
|
||||
public class MenuView extends GenericTreeSortSupportEntity<String> implements MultipleI18nSupportEntity {
|
||||
|
||||
/**
|
||||
* 在多应用集成运行时使用此字段来区分菜单属于哪个系统
|
||||
* 具体标识由各应用前端进行定义
|
||||
*/
|
||||
@Schema(description = "菜单所有者")
|
||||
private String owner;
|
||||
|
||||
|
|
@ -37,6 +42,9 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
@Schema(description = "父节点")
|
||||
private String parentId;
|
||||
|
||||
@Schema(description = "描述")
|
||||
private String describe;
|
||||
|
||||
@Schema(description = "按钮")
|
||||
private List<ButtonView> buttons;
|
||||
|
||||
|
|
@ -55,6 +63,22 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
@Schema(description = "是否已授权")
|
||||
private boolean granted;
|
||||
|
||||
@Schema(title = "国际化信息定义")
|
||||
private Map<String, Map<String, String>> i18nMessages;
|
||||
|
||||
|
||||
public String getI18nName() {
|
||||
return getI18nMessage("name", name);
|
||||
}
|
||||
|
||||
public String getI18nName(Locale locale) {
|
||||
return getI18nMessage("name", locale, name);
|
||||
}
|
||||
|
||||
public static MenuView create() {
|
||||
return EntityFactoryHolder.newInstance(MenuView.class, MenuView::new);
|
||||
}
|
||||
|
||||
public MenuView withGranted(MenuView granted) {
|
||||
if (granted == null) {
|
||||
return this;
|
||||
|
|
@ -104,6 +128,7 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
button.granted = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void resetGrant() {
|
||||
|
|
@ -117,9 +142,7 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
@NoArgsConstructor
|
||||
public static class ButtonView implements Serializable {
|
||||
public static class ButtonView implements SingleI18nSupportEntity, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "按钮ID")
|
||||
|
|
@ -141,18 +164,48 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
@Schema(description = "是否已授权")
|
||||
private boolean granted;
|
||||
|
||||
@Schema(title = "国际化信息定义")
|
||||
private Map<String, String> i18nMessages;
|
||||
|
||||
|
||||
public String getI18nName() {
|
||||
return getI18nMessage("name", name);
|
||||
}
|
||||
|
||||
public ButtonView() {
|
||||
}
|
||||
|
||||
public static ButtonView create() {
|
||||
return EntityFactoryHolder.newInstance(ButtonView.class, ButtonView::new);
|
||||
}
|
||||
|
||||
public static ButtonView of(String id, String name, String description, Map<String, Object> options) {
|
||||
return ButtonView.of(id, name, description, options, true, true);
|
||||
}
|
||||
|
||||
public static ButtonView copy(ButtonView button) {
|
||||
return ButtonView.of(button.getId(), button.getName(), button.getDescription(), button.getOptions());
|
||||
}
|
||||
|
||||
public static ButtonView of(String id, String name, String description, Map<String, Object> options, boolean enabled, boolean granted) {
|
||||
ButtonView view = ButtonView.create();
|
||||
view.setId(id);
|
||||
view.setName(name);
|
||||
view.setDescription(description);
|
||||
view.setOptions(options);
|
||||
view.setEnabled(enabled);
|
||||
view.setGranted(granted);
|
||||
return view;
|
||||
}
|
||||
|
||||
public ButtonView copy() {
|
||||
return FastBeanCopier.copy(this, new ButtonView());
|
||||
return FastBeanCopier.copy(this, create());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static MenuView of(MenuEntity entity) {
|
||||
return FastBeanCopier.copy(entity, new MenuView());
|
||||
return FastBeanCopier.copy(entity, MenuView.create());
|
||||
}
|
||||
|
||||
public static MenuView of(MenuEntity entity, List<MenuBindEntity> binds) {
|
||||
|
|
@ -166,8 +219,14 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
}
|
||||
//重新排序
|
||||
binds.sort(Comparator.comparing(MenuBindEntity::getPriority));
|
||||
Map<String, ButtonView> buttons = new LinkedHashMap<>();
|
||||
Map<String, MenuView.ButtonView> buttons = new LinkedHashMap<>();
|
||||
|
||||
Map<String, ButtonView> buttonViewMap = Optional
|
||||
.ofNullable(view.getButtons())
|
||||
.map(list -> list
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ButtonView::getId, Function.identity())))
|
||||
.orElse(new HashMap<>());
|
||||
for (MenuBindEntity bind : binds) {
|
||||
//不合并则清空之前的配置
|
||||
if (!bind.getMerge()) {
|
||||
|
|
@ -180,8 +239,9 @@ public class MenuView extends GenericTreeSortSupportEntity<String> {
|
|||
//按钮权限
|
||||
if (CollectionUtils.isNotEmpty(bind.getButtons())) {
|
||||
for (ButtonView button : bind.getButtons()) {
|
||||
if (button.isGranted()) {
|
||||
buttons.put(button.getId(), button);
|
||||
ButtonView buttonView = buttonViewMap.get(button.getId());
|
||||
if (button.isGranted() && buttonView != null) {
|
||||
buttons.put(buttonView.getId(), ButtonView.copy(buttonView));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ public class UserAutoInitialize implements CommandLineRunner {
|
|||
}
|
||||
|
||||
private Mono<UserEntity> initAdminUser(UserEntity entity) {
|
||||
|
||||
entity.setCreatorId("system");
|
||||
if (entity.getName() == null) {
|
||||
entity.setName(entity.getUsername());
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<properties>
|
||||
<docker.image.name>registry.cn-shenzhen.aliyuncs.com/jetlinks/${project.artifactId}</docker.image.name>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
|
||||
<jetlinks.ui.version>2.3.0-SNAPSHOT</jetlinks.ui.version>
|
||||
<jetlinks.ui.version>${project.version}</jetlinks.ui.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
|
@ -315,6 +315,12 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>swagger-ui</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@ logging:
|
|||
"io.vertx.core.impl.ContextImpl": off
|
||||
"org.hswebframework.web.starter.jackson": warn
|
||||
"org.jetlinks.community.timescaledb.impl.DefaultTimescaleDBDataWriter": warn
|
||||
"io.scalecube": warn
|
||||
config: classpath:logback-spring.xml
|
||||
vertx:
|
||||
max-event-loop-execute-time-unit: seconds
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<script type="text/javascript">
|
||||
window.location.href="/admin/index.html";
|
||||
</script>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -7,11 +7,12 @@
|
|||
<property name="LOG_EXCEPTION_CONVERSION_WORD" value="%shortened"/>
|
||||
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
<property name="LOG_FILE" value="./logs/jetlinks-community.log"/>
|
||||
<property name="LOG_FILE" value="./data/logs/jetlinks-community.log"/>
|
||||
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
|
||||
|
||||
<appender name="LOGEventPublisher" class="org.jetlinks.community.logging.logback.SystemLoggingAppender"/>
|
||||
<logger name="org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker" level="ERROR" />
|
||||
|
||||
<appender name="ErrorLOGEventPublisher" class="org.jetlinks.community.logging.logback.SystemLoggingAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
|
|
|
|||
Loading…
Reference in New Issue