diff --git a/backend/deploy/systemd/iot-alarm.service b/backend/deploy/systemd/iot-alarm.service new file mode 100644 index 0000000..d3d8584 --- /dev/null +++ b/backend/deploy/systemd/iot-alarm.service @@ -0,0 +1,21 @@ +[Unit] +Description=IoT Alarm Service (9084) +After=docker.service network.target +Requires=docker.service + +[Service] +Type=simple +User=tonzou +WorkingDirectory=/opt/iotsaas/backend/jars +# 日志根目录:logback-spring.xml 中 ${LOG_DIR:-logs/app} 读取该环境变量 +Environment="LOG_DIR=/opt/iotsaas/logs/app" +ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar /opt/iotsaas/backend/jars/iot-alarm-1.0.0.jar +SuccessExitStatus=143 +Restart=on-failure +RestartSec=10 +# 控制台输出交由 systemd journal(自带轮转与体积上限),不再写无轮转的 *.out +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target diff --git a/backend/deploy/systemd/iot-data.service b/backend/deploy/systemd/iot-data.service new file mode 100644 index 0000000..b1e7481 --- /dev/null +++ b/backend/deploy/systemd/iot-data.service @@ -0,0 +1,21 @@ +[Unit] +Description=IoT Data Collection Service (9082) +After=docker.service network.target +Requires=docker.service + +[Service] +Type=simple +User=tonzou +WorkingDirectory=/opt/iotsaas/backend/jars +# 日志根目录:logback-spring.xml 中 ${LOG_DIR:-logs/app} 读取该环境变量 +Environment="LOG_DIR=/opt/iotsaas/logs/app" +ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar /opt/iotsaas/backend/jars/iot-data-1.0.0.jar +SuccessExitStatus=143 +Restart=on-failure +RestartSec=10 +# 控制台输出交由 systemd journal(自带轮转与体积上限),不再写无轮转的 *.out +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target diff --git a/backend/deploy/systemd/iot-device.service b/backend/deploy/systemd/iot-device.service new file mode 100644 index 0000000..5d1f24e --- /dev/null +++ b/backend/deploy/systemd/iot-device.service @@ -0,0 +1,23 @@ +[Unit] +Description=IoT Device Service (9081) +After=docker.service network.target +Requires=docker.service + +[Service] +Type=simple +User=tonzou +WorkingDirectory=/opt/iotsaas/backend/jars +# 日志根目录:logback-spring.xml 中 ${LOG_DIR:-logs/app} 读取该环境变量, +# 滚动日志落到 /opt/iotsaas/logs/app/iot-device.log(按日+50MB 切分,保留 7 天) +Environment="LOG_DIR=/opt/iotsaas/logs/app" +ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar /opt/iotsaas/backend/jars/iot-device-1.0.0-exec.jar +SuccessExitStatus=143 +Restart=on-failure +RestartSec=10 +# 控制台输出交由 systemd journal(自带轮转与体积上限), +# 不再写 append:*.out 这类无轮转文件(曾膨胀到 613MB) +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target diff --git a/backend/deploy/systemd/iot-rule.service b/backend/deploy/systemd/iot-rule.service new file mode 100644 index 0000000..017f39b --- /dev/null +++ b/backend/deploy/systemd/iot-rule.service @@ -0,0 +1,21 @@ +[Unit] +Description=IoT Rule Engine Service (9083) +After=docker.service network.target +Requires=docker.service + +[Service] +Type=simple +User=tonzou +WorkingDirectory=/opt/iotsaas/backend/jars +# 日志根目录:logback-spring.xml 中 ${LOG_DIR:-logs/app} 读取该环境变量 +Environment="LOG_DIR=/opt/iotsaas/logs/app" +ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar /opt/iotsaas/backend/jars/iot-rule-1.0.0.jar +SuccessExitStatus=143 +Restart=on-failure +RestartSec=10 +# 控制台输出交由 systemd journal(自带轮转与体积上限),不再写无轮转的 *.out +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target diff --git a/backend/deploy/systemd/journald-iotsaas.conf b/backend/deploy/systemd/journald-iotsaas.conf new file mode 100644 index 0000000..6c5585d --- /dev/null +++ b/backend/deploy/systemd/journald-iotsaas.conf @@ -0,0 +1,8 @@ +[Journal] +# iotsaas 日志治理:限制 journal 体积,避免 /var/log/journal 无限增长 +# (Ubuntu 默认 SystemMaxUse = 磁盘的 10%,本机 1.8T 盘即 180G,过大) +Storage=persistent +SystemMaxUse=1G +SystemMaxFileSize=50M +SystemMaxFileSec=1day +MaxRetentionSec=7day diff --git a/backend/iot-alarm/src/main/resources/application.yml b/backend/iot-alarm/src/main/resources/application.yml index 92fe82f..c95b493 100644 --- a/backend/iot-alarm/src/main/resources/application.yml +++ b/backend/iot-alarm/src/main/resources/application.yml @@ -95,7 +95,10 @@ mybatis-plus: # 日志配置 logging: + # 显式指定日志配置:涂鸦 open-mq-sdk jar 内自带 logback.xml 会被抢占, + # 强制使用统一配置(文件本体在 iot-common,构建时复制到本模块),含滚动切分与保留策略 + config: classpath:logback-spring.xml level: root: INFO - com.iot: DEBUG - com.iot.alarm: DEBUG + com.iot: INFO + com.iot.alarm: INFO diff --git a/backend/iot-common/src/main/resources/logback-spring.xml b/backend/iot-common/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..a8305fe --- /dev/null +++ b/backend/iot-common/src/main/resources/logback-spring.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + ${LOG_PATTERN} + UTF-8 + + + + + + ${LOG_FILE} + + ${LOG_FILE_PATTERN} + 50MB + 7 + 2GB + true + + + ${LOG_PATTERN} + UTF-8 + + + + + + ${ERR_FILE} + + ERROR + ACCEPT + DENY + + + ${ERR_FILE_PATTERN} + 20MB + 30 + 512MB + true + + + ${LOG_PATTERN} + UTF-8 + + + + + + + + + + + + + + + + + + diff --git a/backend/iot-data/src/main/resources/application.yml b/backend/iot-data/src/main/resources/application.yml index 4160093..ba9e15d 100644 --- a/backend/iot-data/src/main/resources/application.yml +++ b/backend/iot-data/src/main/resources/application.yml @@ -84,7 +84,10 @@ mybatis-plus: # 日志配置 logging: + # 显式指定日志配置:涂鸦 open-mq-sdk jar 内自带 logback.xml 会被抢占, + # 强制使用统一配置(文件本体在 iot-common,构建时复制到本模块),含滚动切分与保留策略 + config: classpath:logback-spring.xml level: root: INFO - com.iot: DEBUG - com.iot.data: DEBUG + com.iot: INFO + com.iot.data: INFO diff --git a/backend/iot-device/src/main/resources/application.yml b/backend/iot-device/src/main/resources/application.yml index 1933b17..33f0543 100644 --- a/backend/iot-device/src/main/resources/application.yml +++ b/backend/iot-device/src/main/resources/application.yml @@ -111,14 +111,14 @@ xxl: logging: # 显式指定日志配置:涂鸦 open-mq-sdk jar 内自带 logback.xml 会被标准 logback # 自动初始化命中并抢占日志输出(控制台无日志、日志写入 ./logs/ 相对目录), - # 这里强制使用本应用的 logback-spring.xml 覆盖之 + # 这里强制使用本应用的 logback-spring.xml 覆盖之(文件本体在 iot-common,构建时复制到本模块) config: classpath:logback-spring.xml level: root: INFO - com.iot: DEBUG - com.iot.device: DEBUG - pattern: - console: '%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n' + # 生产环境保持 INFO:MyBatis mapper 的 SQL 日志在 DEBUG 级别, + # 打开后每条 SQL 打印两次,单日可产生上万条日志并撑大日志文件 + com.iot: INFO + com.iot.device: INFO # Swagger配置 knife4j: diff --git a/backend/iot-device/src/main/resources/logback-spring.xml b/backend/iot-device/src/main/resources/logback-spring.xml deleted file mode 100644 index c33cf02..0000000 --- a/backend/iot-device/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - diff --git a/backend/iot-rule/src/main/resources/application.yml b/backend/iot-rule/src/main/resources/application.yml index c9cf3d8..3ef34c1 100644 --- a/backend/iot-rule/src/main/resources/application.yml +++ b/backend/iot-rule/src/main/resources/application.yml @@ -97,8 +97,11 @@ mybatis-plus: # 日志配置 logging: + # 显式指定日志配置:涂鸦 open-mq-sdk jar 内自带 logback.xml 会被抢占, + # 强制使用统一配置(文件本体在 iot-common,构建时复制到本模块),含滚动切分与保留策略 + config: classpath:logback-spring.xml level: root: INFO - com.iot: DEBUG - com.iot.rule: DEBUG + com.iot: INFO + com.iot.rule: INFO org.drools: INFO diff --git a/backend/pom.xml b/backend/pom.xml index 02ef6e4..fb6a7b9 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -199,6 +199,37 @@ org.apache.maven.plugins maven-compiler-plugin + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-logback-config + process-resources + + copy-resources + + + ${project.build.outputDirectory} + true + + + ${project.basedir}/../iot-common/src/main/resources + + logback-spring.xml + + false + + + + + + diff --git a/deploy-all.bat b/deploy-all.bat index 8ca3291..715e96f 100644 --- a/deploy-all.bat +++ b/deploy-all.bat @@ -25,7 +25,7 @@ set JAR_ALARM=iot-alarm-1.0.0.jar :: ============ 1) 后端构建(含共享模块 iot-common) ============ cd /d %BACKEND_DIR% echo ============================================ -echo [1/7] Maven 重新构建 4 个服务(含共享模块 iot-common) +echo [1/8] Maven 重新构建 4 个服务(含共享模块 iot-common) echo ============================================ call mvn clean package -pl iot-device,iot-data,iot-rule,iot-alarm -am -DskipTests if %ERRORLEVEL% NEQ 0 ( echo [错误] 后端构建失败,已中止。 & pause & exit /b 1 ) @@ -33,7 +33,7 @@ echo [OK] 后端构建成功。 :: ============ 2) 上传 4 个 jar ============ echo ============================================ -echo [2/7] 上传 4 个 jar 到服务器 %SRV_JARS% +echo [2/8] 上传 4 个 jar 到服务器 %SRV_JARS% echo ============================================ tar cf - -C %BACKEND_DIR%\iot-device\target %JAR_DEV% -C %BACKEND_DIR%\iot-data\target %JAR_DATA% -C %BACKEND_DIR%\iot-rule\target %JAR_RULE% -C %BACKEND_DIR%\iot-alarm\target %JAR_ALARM% | %PLINK% %PLINK_OPTS% tar xf - -C %SRV_JARS% if %ERRORLEVEL% NEQ 0 ( echo [错误] jar 上传失败。 & pause & exit /b 1 ) @@ -41,7 +41,7 @@ echo [OK] jar 上传完成。 :: ============ 2.5) 数据库迁移(Flyway 在本环境未启用,按 DB 内 tracking 表应用未执行的 V 迁移) ============ echo ============================================ -echo [3/7] 应用未执行的 SQL 迁移(%BACKEND_DIR%\sql\V*.sql,按 db_migrations_applied 去重) +echo [3/8] 应用未执行的 SQL 迁移(%BACKEND_DIR%\sql\V*.sql,按 db_migrations_applied 去重) echo ============================================ set MIG_DIR=%BACKEND_DIR%\sql set CHK_FILE=%TEMP%\_mig_chk.txt @@ -58,9 +58,23 @@ REM 应用未记录的 V 迁移(新增迁移文件会自动在此补跑,无 for /f "delims=" %%F in ('dir /b /on "%MIG_DIR%\V*.sql"') do call :mig_apply "%%F" echo [OK] 迁移步骤完成。 +::: ============ 3.5) 日志治理:同步 systemd 单元 + journald 限额,清理无轮转的历史 .out ============ +echo ============================================ +echo [4/8] 同步 systemd 单元与 journald 限额(日志轮转治理),并清理历史无轮转 .out/.err +echo ============================================ +%PLINK% %PLINK_OPTS% "rm -rf /tmp/iotsaas-units && mkdir -p /tmp/iotsaas-units" +tar cf - -C %BACKEND_DIR%\deploy\systemd . | %PLINK% %PLINK_OPTS% tar xf - -C /tmp/iotsaas-units +if %ERRORLEVEL% NEQ 0 ( echo [错误] systemd 单元上传失败。 & pause & exit /b 1 ) +%PLINK% %PLINK_OPTS% "echo 'Tonzou@888' | sudo -S -p '' cp /tmp/iotsaas-units/iot-device.service /tmp/iotsaas-units/iot-data.service /tmp/iotsaas-units/iot-rule.service /tmp/iotsaas-units/iot-alarm.service /etc/systemd/system/ && echo 'Tonzou@888' | sudo -S -p '' mkdir -p /etc/systemd/journald.conf.d && echo 'Tonzou@888' | sudo -S -p '' cp /tmp/iotsaas-units/journald-iotsaas.conf /etc/systemd/journald.conf.d/iotsaas.conf" +if %ERRORLEVEL% NEQ 0 ( echo [错误] systemd 单元安装失败。 & pause & exit /b 1 ) +%PLINK% %PLINK_OPTS% "echo 'Tonzou@888' | sudo -S -p '' systemctl daemon-reload && echo 'Tonzou@888' | sudo -S -p '' systemctl restart systemd-journald" +REM 清理历史无轮转的 .out/.err(内容已由 journal 与滚动日志文件接管),并准备滚动日志目录 +%PLINK% %PLINK_OPTS% "echo 'Tonzou@888' | sudo -S -p '' rm -f /opt/iotsaas/logs/*.out /opt/iotsaas/logs/*.err && echo 'Tonzou@888' | sudo -S -p '' rm -rf /opt/iotsaas/backend/jars/logs && echo 'Tonzou@888' | sudo -S -p '' mkdir -p /opt/iotsaas/logs/app && echo 'Tonzou@888' | sudo -S -p '' chown -R tonzou:tonzou /opt/iotsaas/logs" +echo [OK] systemd 单元与 journald 限额已同步,历史 .out 已清理。 + :: ============ 3) 重启 4 个后端服务 ============ echo ============================================ -echo [4/7] 重启 4 个后端服务(systemd) +echo [5/8] 重启 4 个后端服务(systemd) echo ============================================ %PLINK% %PLINK_OPTS% "echo 'Tonzou@888' | sudo -S -p '' systemctl restart iot-device iot-data iot-rule iot-alarm" 2>nul if %ERRORLEVEL% NEQ 0 ( echo [错误] 服务重启失败。 & pause & exit /b 1 ) @@ -69,7 +83,7 @@ echo [OK] 重启命令已下发。 :: ============ 4) 构建前端后台(admin) ============ cd /d %ADMIN_DIR% echo ============================================ -echo [5/7] 构建前端后台(admin)— 跳过 vue-tsc 类型检查,直接 vite build +echo [6/8] 构建前端后台(admin)— 跳过 vue-tsc 类型检查,直接 vite build echo ============================================ where node >nul 2>nul || ( echo [错误] 未找到 node,请将其加入 PATH。 & pause & exit /b 1 ) call npx vite build @@ -78,7 +92,7 @@ echo [OK] 前端构建成功(dist 已生成)。 :: ============ 5) 上传前端 dist(先清空旧文件再解包,避免残留旧 hash 资源) ============ echo ============================================ -echo [6/7] 上传前端 dist 到服务器 %SRV_DIST% +echo [7/8] 上传前端 dist 到服务器 %SRV_DIST% echo ============================================ %PLINK% %PLINK_OPTS% "echo 'Tonzou@888' | sudo -S -p '' rm -rf %SRV_DIST% && mkdir -p %SRV_DIST%" if %ERRORLEVEL% NEQ 0 ( echo [错误] 清空远端 dist 失败。 & pause & exit /b 1 ) @@ -88,7 +102,7 @@ echo [OK] dist 上传完成。 :: ============ 6) 确认状态 ============ echo ============================================ -echo [7/7] 等待启动并确认服务状态 +echo [8/8] 等待启动并确认服务状态 echo ============================================ timeout /t 20 /nobreak >nul %PLINK% %PLINK_OPTS% "echo 'Tonzou@888' | sudo -S -p '' systemctl is-active iot-device iot-data iot-rule iot-alarm" 2>nul