refactor: 优化配置

This commit is contained in:
zhouhao 2025-05-15 15:00:34 +08:00
parent 3be58dce1e
commit f194946492
12 changed files with 173 additions and 54 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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)
);
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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));
}
}
}

View File

@ -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());

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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">

2
run.sh
View File

@ -4,5 +4,5 @@
if [ $? -ne 0 ];then
echo "构建失败!"
else
java -jar "$(pwd)/jetlinks-standalone/target/jetlinks-standalone.jar"
java -jar "$(pwd)/jetlinks-standalone/target/application.jar"
fi