docs: 更新部署运维文档,添加启动脚本与日志配置说明

更新内容:
- 5.2.1 日志配置:添加logback-spring.xml关键配置
  - APP_NAME使用app.instance.name区分多实例
  - LOG_PATTERN直接配置避免shell解析问题
  - 多实例日志隔离示例
- 5.2.2 启动脚本配置:新增章节
  - start.sh核心逻辑说明
  - 关键参数说明表
  - 单实例/多实例启动示例
- 5.2.3 ELK日志收集:章节号调整
- 版本更新:v2.0 -> v2.1
This commit is contained in:
zhangjf 2026-02-22 21:20:29 +08:00
parent 69556c047a
commit 961b669b16

View File

@ -1,7 +1,7 @@
# 资金服务平台部署运维文档 # 资金服务平台部署运维文档
> 版本: v2.0 > 版本: v2.1
> 更新日期: 2026-02-20 > 更新日期: 2026-02-13
> 作者: zhangjf > 作者: zhangjf
--- ---
@ -736,65 +736,138 @@ scrape_configs:
#### 5.2.1 日志配置 #### 5.2.1 日志配置
项目采用 Logback 作为日志框架,支持 **TraceId + SpanId 链路追踪** 项目采用 Logback 作为日志框架,支持 **TraceId + SpanId 链路追踪**
**关键配置**
```xml ```xml
<!-- logback-spring.xml --> <!-- logback-spring.xml 核心配置 -->
<configuration> <configuration>
<!-- APP_NAME使用INSTANCE_NAME区分多实例 -->
<springProperty scope="context" name="APP_NAME" source="app.instance.name" defaultValue="fund-sys"/>
<springProperty scope="context" name="LOG_PATH" source="logging.file.path" defaultValue="/datacfs/applogs"/>
<springProperty scope="context" name="LOG_LEVEL_ROOT" source="logging.level.root" defaultValue="INFO"/>
<springProperty scope="context" name="LOG_LEVEL_APP" source="logging.level.app" defaultValue="DEBUG"/>
<!-- 日志格式直接配置避免shell解析问题 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId:-}][%X{spanId:-}] %-5level %logger{50} - %msg%n"/>
<!-- 控制台输出 --> <!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId:-}][%X{spanId:-}] %-5level %logger{50} - %msg%n</pattern> <pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder> </encoder>
</appender> </appender>
<!-- 文件输出 --> <!-- INFO级别日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/${APP_NAME}/info.log</file> <file>${LOG_PATH}/${APP_NAME}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/${APP_NAME}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <fileNamePattern>${LOG_PATH}/${APP_NAME}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory> <maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize> <maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy> </rollingPolicy>
<encoder> <encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId:-}][%X{spanId:-}] %-5level %logger{50} - %msg%n</pattern> <pattern>${LOG_PATTERN}</pattern>
</encoder> </encoder>
</appender> </appender>
<!-- API请求日志 --> <!-- ERROR级别日志文件 -->
<appender name="AOP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/${APP_NAME}/aop.log</file> <file>${LOG_PATH}/${APP_NAME}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 配置同上 -->
<fileNamePattern>./logs/${APP_NAME}/aop-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender> </appender>
<root level="INFO"> <!-- JSON格式日志(用于ELK采集) -->
<appender-ref ref="CONSOLE"/> <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<appender-ref ref="FILE"/> <file>${LOG_PATH}/${APP_NAME}/json.log</file>
</root> <encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"app_name":"${APP_NAME}"}</customFields>
</encoder>
</appender>
</configuration> </configuration>
``` ```
**多实例日志隔离**
| 实例 | INSTANCE_NAME | 日志目录 |
|------|--------------|---------|
| 普通租户 | `fund-sys` | `/datacfs/applogs/fund-sys/` |
| VIP租户 | `fund-sys-vip` | `/datacfs/applogs/fund-sys-vip/` |
**日志文件结构** **日志文件结构**
``` ```
logs/ /datacfs/applogs/
├── fund-gateway/ ├── fund-gateway/
│ ├── info.log # 主日志 │ ├── info.log # 主日志
│ ├── error.log # 错误日志 │ ├── error.log # 错误日志
│ └── aop.log # API请求日志 │ ├── json.log # JSON格式日志(ELK)
│ ├── aop.log # API请求日志
│ └── stdout.log # 标准输出日志
├── fund-sys/ ├── fund-sys/
│ ├── info.log │ ├── info.log
│ ├── error.log │ ├── error.log
│ └── aop.log │ └── ...
└── ... └── fund-sys-vip/ # VIP租户实例
├── info.log
└── ...
``` ```
#### 5.2.2 ELK 日志收集 #### 5.2.2 启动脚本配置
启动脚本支持多租户多实例部署,关键特性:
```bash
# start.sh 核心逻辑
# 1. 加载配置文件
load_properties "${APP_HOME}/conf/env.properties"
load_properties "${APP_HOME}/conf/service.properties"
# 2. INSTANCE_NAME处理
# 如果INSTANCE_NAME为空自动使用APP_NAME
if [[ -z "${INSTANCE_NAME}" ]]; then
INSTANCE_NAME=${APP_NAME}
fi
# 3. ClassPath配置lib/*:conf
CLASSPATH="${APP_HOME}/lib/*:${APP_HOME}/conf"
# 4. JVM参数
JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
# 5. 日志参数使用INSTANCE_NAME区分实例
LOG_OPTS="-Dlogging.file.path=${LOG_HOME}"
LOG_OPTS="$LOG_OPTS -Dapp.instance.name=${INSTANCE_NAME}"
# 6. 启动命令java -cp模式
nohup java $JAVA_OPTS $LOG_OPTS $TENANT_OPTS -cp "$CLASSPATH" $MAIN_CLASS >${LOG_HOME}/${INSTANCE_NAME}/stdout.log 2>&1 &
```
**关键参数说明**
| 参数 | 说明 | 来源 |
|------|------|------|
| `APP_NAME` | 服务名称 | service.properties |
| `INSTANCE_NAME` | 实例名称(唯一) | service.properties空则用APP_NAME |
| `MAIN_CLASS` | 主类 | service.properties |
| `LOG_HOME` | 日志根目录 | env.properties |
| `TENANT_ID` | 租户ID | service.properties |
**启动命令示例**
```bash
# 单实例启动
./bin/start.sh
# 多实例启动VIP租户
INSTANCE_NAME=fund-sys-vip TENANT_ID=vip001 ./bin/start.sh
```
#### 5.2.3 ELK 日志收集
```yaml ```yaml
# filebeat.yml # filebeat.yml