Files
wenzi/docs/CONFIGURATION_GUIDE.md

827 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ⚙️ 配置指南
> 版本: 1.0
> 更新时间: 2026-03-04
## 📋 目录
1. [配置文件结构](#配置文件结构)
2. [环境配置](#环境配置)
3. [数据库配置](#数据库配置)
4. [Redis配置](#redis配置)
5. [安全配置](#安全配置)
6. [性能配置](#性能配置)
7. [日志配置](#日志配置)
8. [环境变量](#环境变量)
## 📁 配置文件结构
```
src/main/resources/
├── application.properties # 主配置文件
├── application-dev.yml # 开发环境配置
├── application-test.yml # 测试环境配置
├── application-prod.yml # 生产环境配置
├── application-e2e.properties # E2E测试配置
└── logback-spring.xml # 日志配置
```
### 配置优先级
1. 命令行参数 (`--spring.datasource.url=...`)
2. 环境变量 (`SPRING_DATASOURCE_URL`)
3. 外部配置文件 (`/opt/mosquito/application-prod.yml`)
4. 内部配置文件 (`classpath:application-prod.yml`)
5. 默认配置 (`application.properties`)
## 🌍 环境配置
### 开发环境 (dev)
`application-dev.yml`:
```yaml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mosquito_dev
username: mosquito
password: dev_password
hikari:
maximum-pool-size: 10
minimum-idle: 2
data:
redis:
host: localhost
port: 6379
password: dev_redis_password
flyway:
enabled: true
baseline-on-migrate: true
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
app:
api-key:
encryption-key: dev_32_char_encryption_key_12
rate-limit:
per-minute: 1000
poster:
cache-enabled: false
logging:
level:
root: INFO
com.mosquito.project: DEBUG
org.springframework.web: DEBUG
```
### 测试环境 (test)
`application-test.yml`:
```yaml
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
data:
redis:
host: localhost
port: 6379
flyway:
enabled: true
jpa:
hibernate:
ddl-auto: validate
app:
api-key:
encryption-key: test_32_char_encryption_key_12
rate-limit:
per-minute: 10000
poster:
cache-enabled: false
logging:
level:
root: WARN
com.mosquito.project: INFO
```
### 生产环境 (prod)
`application-prod.yml`:
```yaml
spring:
datasource:
url: ${DB_URL:jdbc:postgresql://localhost:5432/mosquito_prod}
username: ${DB_USERNAME:mosquito_prod}
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
leak-detection-threshold: 60000
data:
redis:
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD}
timeout: 3000ms
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5
max-wait: 3000ms
flyway:
enabled: true
baseline-on-migrate: true
validate-on-migrate: true
jpa:
show-sql: false
properties:
hibernate:
jdbc:
batch_size: 20
order_inserts: true
order_updates: true
app:
api-key:
encryption-key: ${API_KEY_ENCRYPTION_KEY}
rate-limit:
per-minute: ${RATE_LIMIT_PER_MINUTE:100}
poster:
cache-enabled: true
cache-ttl: 3600
logging:
level:
root: INFO
com.mosquito.project: INFO
file:
name: /var/log/mosquito/application.log
max-size: 100MB
max-history: 30
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: when-authorized
```
## 🗄️ 数据库配置
### PostgreSQL连接池
```yaml
spring:
datasource:
hikari:
# 最大连接数推荐CPU核心数 * 2 + 磁盘数)
maximum-pool-size: 20
# 最小空闲连接数
minimum-idle: 5
# 连接超时(毫秒)
connection-timeout: 30000
# 空闲超时(毫秒)
idle-timeout: 600000
# 连接最大生命周期(毫秒)
max-lifetime: 1800000
# 连接泄漏检测阈值(毫秒)
leak-detection-threshold: 60000
# 连接测试查询
connection-test-query: SELECT 1
```
### Flyway迁移配置
```yaml
spring:
flyway:
# 启用Flyway
enabled: true
# 迁移脚本位置
locations: classpath:db/migration
# 基线版本
baseline-version: 1
# 在迁移时创建基线
baseline-on-migrate: true
# 验证迁移
validate-on-migrate: true
# 清理数据库(生产环境禁用)
clean-disabled: true
# 占位符
placeholders:
schema: public
```
### JPA/Hibernate配置
```yaml
spring:
jpa:
# 显示SQL仅开发环境
show-sql: false
# DDL策略生产环境使用validate
hibernate:
ddl-auto: validate
properties:
hibernate:
# SQL格式化
format_sql: true
# 批量操作
jdbc:
batch_size: 20
order_inserts: true
order_updates: true
# 二级缓存
cache:
use_second_level_cache: true
region:
factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
# 查询缓存
cache:
use_query_cache: true
```
## 🔴 Redis配置
### 基础配置
```yaml
spring:
data:
redis:
# Redis服务器地址
host: ${REDIS_HOST:localhost}
# Redis端口
port: ${REDIS_PORT:6379}
# Redis密码
password: ${REDIS_PASSWORD}
# 数据库索引
database: 0
# 连接超时
timeout: 3000ms
# Lettuce连接池
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5
max-wait: 3000ms
# 关闭超时
shutdown-timeout: 100ms
```
### 缓存配置
```yaml
spring:
cache:
type: redis
redis:
# 缓存TTL毫秒
time-to-live: 3600000
# 缓存null值
cache-null-values: false
# 键前缀
key-prefix: "mosquito:"
# 使用键前缀
use-key-prefix: true
app:
cache:
# 活动缓存TTL
activity-ttl: 3600
# 统计缓存TTL
stats-ttl: 300
# 排行榜缓存TTL
leaderboard-ttl: 60
```
### Redis Sentinel配置高可用
```yaml
spring:
data:
redis:
sentinel:
master: mymaster
nodes:
- 192.168.1.10:26379
- 192.168.1.11:26379
- 192.168.1.12:26379
password: ${REDIS_PASSWORD}
```
### Redis Cluster配置集群
```yaml
spring:
data:
redis:
cluster:
nodes:
- 192.168.1.10:6379
- 192.168.1.11:6379
- 192.168.1.12:6379
- 192.168.1.13:6379
- 192.168.1.14:6379
- 192.168.1.15:6379
max-redirects: 3
password: ${REDIS_PASSWORD}
```
## 🔐 安全配置
### 回调API白名单配置
系统对回调API请求进行IP白名单验证确保只有受信任的服务器才能调用回调接口。
#### 回调白名单配置项
```yaml
app:
callback:
# IP白名单列表用逗号分隔
# 生产环境必须配置否则启动会失败fail-fast
whitelist:
ips: "203.0.113.1,198.51.100.1,10.0.0.0/8"
# 宽松模式(仅用于开发/测试环境)
# 设为true时跳过IP白名单验证
whitelist:
permissive: false
```
#### 环境变量配置
```bash
# 方式1直接配置IP白名单推荐生产环境使用
export MOSQUITO_CALLBACK_WHITELIST_IPS="203.0.113.1,198.51.100.1"
# 方式2启用宽松模式仅用于开发/测试)
export MOSQUITO_CALLBACK_WHITELIST_PERMISSIVE="true"
# Spring配置方式
export MOSQUITO_CALLBACK_WHITELIST_IPS="203.0.113.1,198.51.100.1"
```
#### 生产环境配置示例
```yaml
# application-prod.yml
app:
callback:
whitelist:
ips: "${MOSQUITO_CALLBACK_WHITELIST_IPS}"
permissive: false
```
生产环境启动前检查清单:
1. **确认已配置IP白名单**
```bash
# 检查环境变量
echo $MOSQUITO_CALLBACK_WHITELIST_IPS
# 如果未配置,启动会失败并报错:
# "生产环境回调白名单配置缺失!请配置 mosquito.callback.whitelist.ips 或启用 permissive 模式。"
```
2. **配置CIDR格式IP段**
```bash
# 支持CIDR格式但需注意系统使用简单字符串分割不支持严格的CIDR解析
# 推荐列出所有具体IP或使用云服务商的弹性IP
export MOSQUITO_CALLBACK_WHITELIST_IPS="203.0.113.1,198.51.100.10,198.51.100.20"
```
3. **常见云服务商IP段**
```bash
# 阿里云ECS需要根据实际配置
export MOSQUITO_CALLBACK_WHITELIST_IPS="10.0.0.0/8,172.16.0.0/12"
# AWS EC2
export MOSQUITO_CALLBACK_WHITELIST_IPS="3.0.0.0/8,18.0.0.0/8"
```
#### 开发/测试环境配置
```yaml
# application-dev.yml
app:
callback:
whitelist:
permissive: true # 跳过白名单验证
```
或通过环境变量:
```bash
# 开发环境
export MOSQUITO_CALLBACK_WHITELIST_PERMISSIVE="true"
# 测试环境(使用测试配置)
export SPRING_PROFILES_ACTIVE=test
```
#### 故障排查
| 错误信息 | 原因 | 解决方案 |
|---------|------|---------|
| "生产环境回调白名单配置缺失" | 未配置`mosquito.callback.whitelist.ips` | 配置IP白名单或启用permissive模式 |
| "来源IP不在白名单中" | 回调请求IP不在白名单中 | 将该IP添加到白名单 |
| "启动失败" | 生产环境未配置白名单 | 配置`MOSQUITO_CALLBACK_WHITELIST_IPS` |
#### 白名单验证逻辑
- 系统启动时如果`permissive=false`且`ips`为空会抛出异常阻止启动fail-fast
- 每个回调请求都会验证来源IP是否在白名单中
- 不在白名单中的请求会被拒绝并返回`IP_NOT_WHITELISTED`错误
### API密钥加密
```yaml
app:
api-key:
# 加密密钥必须32字符
encryption-key: ${API_KEY_ENCRYPTION_KEY}
# PBKDF2迭代次数
pbkdf2-iterations: 10000
# 密钥长度
key-length: 256
```
生成加密密钥:
```bash
# 生成32字符随机密钥
openssl rand -base64 24 | head -c 32
```
### 速率限制
```yaml
app:
rate-limit:
# 每分钟请求限制
per-minute: ${RATE_LIMIT_PER_MINUTE:100}
# 限流键前缀
key-prefix: "rate_limit:"
# 限流窗口(秒)
window-seconds: 60
```
### CORS配置
```yaml
app:
cors:
# 允许的源
allowed-origins:
- https://example.com
- https://www.example.com
# 允许的方法
allowed-methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
# 允许的头
allowed-headers:
- "*"
# 暴露的头
exposed-headers:
- X-API-Version
- X-RateLimit-Remaining
# 允许凭证
allow-credentials: true
# 预检请求缓存时间(秒)
max-age: 3600
```
## ⚡ 性能配置
### 线程池配置
```yaml
spring:
task:
execution:
pool:
# 核心线程数
core-size: 8
# 最大线程数
max-size: 16
# 队列容量
queue-capacity: 100
# 线程名前缀
thread-name-prefix: "async-"
# 空闲线程存活时间(秒)
keep-alive: 60s
```
### HTTP客户端配置
```yaml
app:
http-client:
# 连接超时(毫秒)
connect-timeout: 5000
# 读取超时(毫秒)
read-timeout: 10000
# 最大连接数
max-connections: 100
# 每个路由的最大连接数
max-connections-per-route: 20
```
### 海报生成配置
```yaml
app:
poster:
# 启用缓存
cache-enabled: true
# 缓存TTL
cache-ttl: 3600
# 图片质量0.0-1.0
image-quality: 0.9
# 图片格式
image-format: PNG
# 最大宽度
max-width: 1080
# 最大高度
max-height: 1920
```
## 📝 日志配置
### Logback配置
`logback-spring.xml`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 开发环境 -->
<springProfile name="dev">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<logger name="com.mosquito.project" level="DEBUG" />
<logger name="org.springframework.web" level="DEBUG" />
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<!-- 文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/mosquito/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/var/log/mosquito/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 错误日志单独输出 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/mosquito/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/var/log/mosquito/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<logger name="com.mosquito.project" level="INFO" />
</springProfile>
</configuration>
```
### 日志级别
```yaml
logging:
level:
# 根日志级别
root: INFO
# 应用日志
com.mosquito.project: INFO
# Spring框架
org.springframework: INFO
org.springframework.web: INFO
org.springframework.security: INFO
# Hibernate
org.hibernate: INFO
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
# Redis
org.springframework.data.redis: INFO
# Flyway
org.flywaydb: INFO
```
## 🌐 环境变量
### 必需环境变量
```bash
# 数据库配置
export DB_URL="jdbc:postgresql://localhost:5432/mosquito_prod"
export DB_USERNAME="mosquito_prod"
export DB_PASSWORD="your_secure_password"
# Redis配置
export REDIS_HOST="localhost"
export REDIS_PORT="6379"
export REDIS_PASSWORD="your_redis_password"
# 安全配置
export API_KEY_ENCRYPTION_KEY="your_32_char_encryption_key_12"
```
### 可选环境变量
```bash
# 速率限制
export RATE_LIMIT_PER_MINUTE="100"
# 日志配置
export LOG_LEVEL="INFO"
export LOG_FILE="/var/log/mosquito/application.log"
# JVM配置
export JAVA_OPTS="-Xms2g -Xmx4g -XX:+UseG1GC"
# Spring配置
export SPRING_PROFILES_ACTIVE="prod"
export SERVER_PORT="8080"
```
### 环境变量文件
创建 `.env` 文件不要提交到Git
```bash
# .env
DB_PASSWORD=your_secure_password
REDIS_PASSWORD=your_redis_password
API_KEY_ENCRYPTION_KEY=your_32_char_encryption_key_12
RATE_LIMIT_PER_MINUTE=100
```
加载环境变量:
```bash
# 使用source加载
source .env
# 或使用export
export $(cat .env | xargs)
```
## 🔧 配置验证
### 启动时验证
```java
@Configuration
public class ConfigValidation {
@Value("${app.api-key.encryption-key}")
private String encryptionKey;
@PostConstruct
public void validate() {
if (encryptionKey.length() != 32) {
throw new IllegalStateException(
"API key encryption key must be exactly 32 characters"
);
}
}
}
```
### 配置检查命令
```bash
# 检查配置文件语法
java -jar mosquito-1.0.0.jar --spring.config.location=application-prod.yml --spring.profiles.active=prod --debug
# 查看实际配置
java -jar mosquito-1.0.0.jar --spring.profiles.active=prod \
--spring.boot.admin.client.enabled=false \
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
```
## 📚 相关资源
- [部署指南](./DEPLOYMENT_GUIDE.md) - 部署说明
- [API文档](./api.md) - API接口文档
- [开发指南](./DEVELOPMENT_GUIDE.md) - 开发环境搭建
---
**文档版本**: 1.0
**最后更新**: 2026-03-04