# 🚀 部署指南
> 版本: 1.0
> 更新时间: 2026-03-04
## 📋 目录
1. [环境要求](#环境要求)
2. [快速部署](#快速部署)
3. [生产环境部署](#生产环境部署)
4. [Docker部署](#docker部署)
5. [数据库迁移](#数据库迁移)
6. [监控与日志](#监控与日志)
7. [故障排查](#故障排查)
## 🔧 环境要求
### 最低要求
| 组件 | 版本要求 | 说明 |
|------|----------|------|
| Java | 17+ | 推荐使用OpenJDK 17或21 |
| PostgreSQL | 12+ | 推荐使用14或15 |
| Redis | 6.0+ | 生产环境必需 |
| Maven | 3.8+ | 构建工具 |
| 内存 | 2GB+ | 推荐4GB |
| 磁盘 | 10GB+ | 包含日志和数据 |
### 推荐配置
**开发环境:**
- CPU: 2核
- 内存: 4GB
- 磁盘: 20GB SSD
**生产环境:**
- CPU: 4核+
- 内存: 8GB+
- 磁盘: 50GB+ SSD
- 负载均衡器(可选)
- 数据库主从复制(推荐)
## ⚡ 快速部署
### 1. 克隆代码
```bash
git clone https://github.com/your-org/mosquito.git
cd mosquito
```
### 2. 配置数据库
```bash
# 创建数据库
psql -U postgres -c "CREATE DATABASE mosquito;"
psql -U postgres -c "CREATE USER mosquito_user WITH PASSWORD 'your_password';"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE mosquito TO mosquito_user;"
```
### 3. 配置环境变量
```bash
# 复制配置模板
cp src/main/resources/application-dev.yml.example src/main/resources/application-dev.yml
# 编辑配置文件
vi src/main/resources/application-dev.yml
```
### 4. 构建项目
```bash
# 跳过测试快速构建
mvn clean package -DskipTests
# 或者运行完整测试
mvn clean package
```
### 5. 启动应用
```bash
java -jar target/mosquito-1.0.0.jar --spring.profiles.active=dev
```
应用将在 `http://localhost:8080` 启动。
## 🏭 生产环境部署
### 1. 准备工作
**创建专用用户:**
```bash
sudo useradd -r -s /bin/false mosquito
sudo mkdir -p /opt/mosquito
sudo chown mosquito:mosquito /opt/mosquito
```
**配置PostgreSQL:**
```sql
-- 创建生产数据库
CREATE DATABASE mosquito_prod;
CREATE USER mosquito_prod WITH PASSWORD 'strong_password_here';
GRANT ALL PRIVILEGES ON DATABASE mosquito_prod TO mosquito_prod;
-- 配置连接池
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET shared_buffers = '2GB';
ALTER SYSTEM SET effective_cache_size = '6GB';
SELECT pg_reload_conf();
```
**配置Redis:**
```bash
# 编辑Redis配置
sudo vi /etc/redis/redis.conf
# 设置密码
requirepass your_redis_password
# 设置最大内存
maxmemory 1gb
maxmemory-policy allkeys-lru
# 启用持久化
save 900 1
save 300 10
save 60 10000
# 重启Redis
sudo systemctl restart redis
```
### 2. 配置应用
创建 `/opt/mosquito/application-prod.yml`:
```yaml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mosquito_prod
username: mosquito_prod
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
data:
redis:
host: localhost
port: 6379
password: ${REDIS_PASSWORD}
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5
flyway:
enabled: true
baseline-on-migrate: true
app:
api-key:
encryption-key: ${API_KEY_ENCRYPTION_KEY}
rate-limit:
per-minute: 100
poster:
cache-enabled: true
logging:
level:
root: INFO
com.mosquito.project: INFO
file:
name: /var/log/mosquito/application.log
max-size: 100MB
max-history: 30
```
### 3. 创建systemd服务
创建 `/etc/systemd/system/mosquito.service`:
```ini
[Unit]
Description=Mosquito Activity Tracking Service
After=network.target postgresql.service redis.service
[Service]
Type=simple
User=mosquito
Group=mosquito
WorkingDirectory=/opt/mosquito
Environment="JAVA_OPTS=-Xms2g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
Environment="DB_PASSWORD=your_db_password"
Environment="REDIS_PASSWORD=your_redis_password"
Environment="API_KEY_ENCRYPTION_KEY=your_32_char_encryption_key"
ExecStart=/usr/bin/java $JAVA_OPTS \
-jar /opt/mosquito/mosquito-1.0.0.jar \
--spring.profiles.active=prod \
--spring.config.location=/opt/mosquito/application-prod.yml
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
```
### 4. 部署应用
```bash
# 复制JAR文件
sudo cp target/mosquito-1.0.0.jar /opt/mosquito/
sudo chown mosquito:mosquito /opt/mosquito/mosquito-1.0.0.jar
# 创建日志目录
sudo mkdir -p /var/log/mosquito
sudo chown mosquito:mosquito /var/log/mosquito
# 重新加载systemd
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start mosquito
# 设置开机自启
sudo systemctl enable mosquito
# 检查状态
sudo systemctl status mosquito
```
### 5. 配置Nginx反向代理
创建 `/etc/nginx/sites-available/mosquito`:
```nginx
upstream mosquito_backend {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
# 重定向到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/mosquito_access.log;
error_log /var/log/nginx/mosquito_error.log;
client_max_body_size 10M;
location / {
proxy_pass http://mosquito_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
location /actuator/health {
proxy_pass http://mosquito_backend;
access_log off;
}
}
```
启用配置:
```bash
sudo ln -s /etc/nginx/sites-available/mosquito /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
## 🐳 Docker部署
### 1. Dockerfile
创建 `Dockerfile`:
```dockerfile
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="your-email@example.com"
LABEL version="1.0.0"
# 创建应用目录
WORKDIR /app
# 复制JAR文件
COPY target/mosquito-1.0.0.jar app.jar
# 创建非root用户
RUN addgroup -S mosquito && adduser -S mosquito -G mosquito
RUN chown -R mosquito:mosquito /app
USER mosquito
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
# 暴露端口
EXPOSE 8080
# JVM参数
ENV JAVA_OPTS="-Xms512m -Xmx1g -XX:+UseG1GC"
# 启动命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
```
### 2. Docker Compose
创建 `docker-compose.yml`:
```yaml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: mosquito-postgres
environment:
POSTGRES_DB: mosquito
POSTGRES_USER: mosquito
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mosquito"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: mosquito-redis
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
app:
build: .
container_name: mosquito-app
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
SPRING_PROFILES_ACTIVE: prod
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/mosquito
SPRING_DATASOURCE_USERNAME: mosquito
SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}
SPRING_DATA_REDIS_HOST: redis
SPRING_DATA_REDIS_PASSWORD: ${REDIS_PASSWORD}
API_KEY_ENCRYPTION_KEY: ${API_KEY_ENCRYPTION_KEY}
ports:
- "8080:8080"
volumes:
- app_logs:/app/logs
restart: unless-stopped
volumes:
postgres_data:
redis_data:
app_logs:
```
### 3. 启动Docker环境
```bash
# 创建.env文件
cat > .env << EOF
DB_PASSWORD=your_db_password
REDIS_PASSWORD=your_redis_password
API_KEY_ENCRYPTION_KEY=your_32_char_encryption_key
EOF
# 构建镜像
docker-compose build
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f app
# 检查状态
docker-compose ps
```
## 🗄️ 数据库迁移
### Flyway自动迁移
应用启动时会自动执行Flyway迁移:
```yaml
spring:
flyway:
enabled: true
baseline-on-migrate: true
locations: classpath:db/migration
```
### 手动迁移
```bash
# 查看迁移状态
mvn flyway:info
# 执行迁移
mvn flyway:migrate
# 回滚(需要Flyway Pro)
mvn flyway:undo
```
### 迁移脚本位置
```
src/main/resources/db/migration/
├── V1__Create_activities_table.sql
├── V2__Create_api_keys_table.sql
├── V3__Create_daily_activity_stats_table.sql
├── ...
└── V20__Add_share_tracking_fields.sql
```
### 生产环境迁移最佳实践
1. **备份数据库**
```bash
pg_dump -U mosquito_prod -h localhost mosquito_prod > backup_$(date +%Y%m%d_%H%M%S).sql
```
2. **在测试环境验证**
```bash
# 恢复到测试环境
psql -U mosquito_test -h localhost mosquito_test < backup.sql
# 运行迁移
mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/mosquito_test
```
3. **执行生产迁移**
```bash
# 停止应用(可选,取决于迁移类型)
sudo systemctl stop mosquito
# 执行迁移
mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/mosquito_prod
# 启动应用
sudo systemctl start mosquito
```
## 📊 监控与日志
### Spring Boot Actuator
启用健康检查和指标:
```yaml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: when-authorized
```
访问端点:
- 健康检查: `http://localhost:8080/actuator/health`
- 指标: `http://localhost:8080/actuator/metrics`
- Prometheus: `http://localhost:8080/actuator/prometheus`
### 日志配置
`logback-spring.xml`:
```xml
/var/log/mosquito/application.log
/var/log/mosquito/application.%d{yyyy-MM-dd}.log
30
10GB
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
```
### 监控工具集成
**Prometheus + Grafana:**
```yaml
# prometheus.yml
scrape_configs:
- job_name: 'mosquito'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['localhost:8080']
```
## 🔍 故障排查
### 常见问题
**1. 应用无法启动**
```bash
# 检查日志
sudo journalctl -u mosquito -n 100 --no-pager
# 检查端口占用
sudo netstat -tlnp | grep 8080
# 检查数据库连接
psql -U mosquito_prod -h localhost -d mosquito_prod -c "SELECT 1;"
```
**2. Redis连接失败**
```bash
# 检查Redis状态
sudo systemctl status redis
# 测试连接
redis-cli -a your_redis_password ping
# 检查配置
redis-cli -a your_redis_password CONFIG GET requirepass
```
**3. 数据库迁移失败**
```bash
# 查看Flyway状态
mvn flyway:info
# 修复失败的迁移
mvn flyway:repair
# 手动执行SQL
psql -U mosquito_prod -h localhost -d mosquito_prod -f src/main/resources/db/migration/V20__xxx.sql
```
**4. 内存不足**
```bash
# 查看JVM内存使用
jcmd VM.native_memory summary
# 调整JVM参数
sudo vi /etc/systemd/system/mosquito.service
# 修改: Environment="JAVA_OPTS=-Xms2g -Xmx4g"
sudo systemctl daemon-reload
sudo systemctl restart mosquito
```
### 性能调优
**JVM参数优化:**
```bash
JAVA_OPTS="
-Xms2g -Xmx4g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/mosquito/heapdump.hprof
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/var/log/mosquito/gc.log
"
```
**数据库连接池:**
```yaml
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
```
## 📚 相关资源
- [配置指南](./CONFIGURATION_GUIDE.md) - 详细配置说明
- [API文档](./api.md) - API接口文档
- [开发指南](./DEVELOPMENT_GUIDE.md) - 开发环境搭建
---
**文档版本**: 1.0
**最后更新**: 2026-03-04