本文档详细介绍 Tagtag Starter 项目在生产环境的部署配置,包括服务器选型、后端部署、前端部署、数据库优化和安全配置等内容。
Tagtag Starter 采用前后端分离架构,生产环境建议使用以下服务器配置:
| 服务类型 | 推荐配置 | 数量 | 用途 |
|---|---|---|---|
| 负载均衡 | 4核8G | 1 | 流量分发、SSL 终止 |
| 后端应用 | 8核16G | 2+ | 运行 Spring Boot 应用 |
| 前端应用 | 4核8G | 2 | 运行 Nginx 服务,部署静态资源 |
| 数据库 | 16核32G | 1主1从 | 运行 MySQL 数据库 |
| Redis | 4核8G | 1主1从 | 缓存、会话存储 |
| 监控 | 4核8G | 1 | 运行 Prometheus、Grafana 等监控工具 |
建议使用 CentOS 7.9 或 Ubuntu 20.04 LTS 作为服务器操作系统。
系统优化建议:
# 关闭不必要的服务
systemctl stop firewalld
systemctl disable firewalld
systemctl stop postfix
systemctl disable postfix
# 设置系统时区
timedatectl set-timezone Asia/Shanghai
# 关闭 SELinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0
# 优化文件描述符限制
cat >> /etc/security/limits.conf << EOF
* soft nofile 65535
* hard nofile 65535
EOF
# 优化内核参数
cat >> /etc/sysctl.conf << EOF
# 网络优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 1024 65535
# 内存优化
vm.swappiness = 10
vm.overcommit_memory = 1
EOF
# 应用内核参数
sysctl -p
步骤:
命令示例:
# 克隆代码
git clone https://github.com/your-org/tagtag.git
cd tagtag
# 配置环境变量
export MAVEN_OPTS="-Xmx2g -Xms1g"
# 构建项目
mvn clean package -DskipTests
# 生成 Docker 镜像(可选)
docker build -t tagtag/backend:latest .
步骤:
示例:
# 创建部署目录
mkdir -p /opt/tagtag/backend
cd /opt/tagtag/backend
# 上传 JAR 文件
scp target/tagtag-backend.jar root@server:/opt/tagtag/backend/
# 创建启动脚本
cat > start.sh << EOF
#!/bin/bash
java -jar -Xmx8g -Xms4g -Dspring.profiles.active=prod tagtag-backend.jar
EOF
chmod +x start.sh
# 配置 Systemd 服务
cat > /etc/systemd/system/tagtag-backend.service << EOF
[Unit]
Description=Tagtag Starter Backend Service
After=network.target
[Service]
User=root
WorkingDirectory=/opt/tagtag/backend
ExecStart=/opt/tagtag/backend/start.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
systemctl daemon-reload
systemctl start tagtag-backend
systemctl enable tagtag-backend
步骤:
Docker Compose 示例:
version: '3.8'
services:
tagtag-backend:
image: tagtag/backend:latest
container_name: tagtag-backend
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- DB_HOST=mysql
- DB_PORT=3306
- DB_USERNAME=root
- DB_PASSWORD=password
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
- mysql
- redis
restart: always
volumes:
- ./logs:/opt/tagtag/logs
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=tagtag
restart: always
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
redis:
image: redis:7.0
container_name: redis
ports:
- "6379:6379"
restart: always
volumes:
- ./redis/data:/data
生产环境配置文件:application-prod.yml
核心配置项:
# 服务器配置
server:
port: 8080
servlet:
context-path: /api
tomcat:
threads:
max: 200
min-spare: 10
connection-timeout: 30000
# 数据库配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/tagtag?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: password
hikari:
maximum-pool-size: 50
minimum-idle: 10
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
# Redis 配置
redis:
host: localhost
port: 6379
password:
database: 0
timeout: 3000ms
lettuce:
pool:
max-active: 100
max-idle: 20
min-idle: 5
max-wait: -1ms
# JWT 配置
jwt:
secret: your-secret-key
expiration: 3600
refresh-expiration: 86400
# 日志配置
logging:
level:
root: info
com.tagtag: debug
file:
name: /opt/tagtag/logs/tagtag.log
max-size: 100MB
max-history: 30
步骤:
命令示例:
# 克隆代码
git clone https://github.com/your-org/tagtag.git
cd tagtag/tagtag-ui
# 安装依赖
pnpm install
# 构建生产版本
pnpm build
# 生成 Docker 镜像(可选)
docker build -t tagtag/frontend:latest .
步骤:
示例:
# 安装 Nginx
yum install -y nginx
# 创建部署目录
mkdir -p /usr/share/nginx/html/tagtag
# 复制静态文件
cp -r dist/* /usr/share/nginx/html/tagtag/
# 配置 Nginx
cat > /etc/nginx/conf.d/tagtag.conf << EOF
server {
listen 80;
server_name tagtag.your-domain.com;
# 静态资源配置
location / {
root /usr/share/nginx/html/tagtag;
index index.html;
try_files $uri $uri/ /index.html;
}
# API 代理配置
location /api {
proxy_pass http://backend-server:8080;
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;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 日志配置
access_log /var/log/nginx/tagtag.access.log main;
error_log /var/log/nginx/tagtag.error.log error;
}
EOF
# 检查 Nginx 配置
nginx -t
# 重启 Nginx
systemctl restart nginx
systemctl enable nginx
步骤:
示例:
# 安装 Certbot
yum install -y epel-release
yum install -y certbot python3-certbot-nginx
# 申请 SSL 证书
certbot --nginx -d tagtag.your-domain.com
# 自动续约
echo "0 3 * * * certbot renew --quiet" >> /var/spool/cron/root
Nginx SSL 配置:
server {
listen 443 ssl http2;
server_name tagtag.your-domain.com;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/tagtag.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tagtag.your-domain.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
# TLS 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS 配置
add_header Strict-Transport-Security "max-age=63072000" always;
# 其他配置...
}
# 强制 HTTPS 跳转
server {
listen 80;
server_name tagtag.your-domain.com;
return 301 https://$server_name$request_uri;
}
核心配置项:
# /etc/my.cnf
[mysqld]
# 基础配置
user = mysql
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
# 内存配置
innodb_buffer_pool_size = 20G # 建议为服务器内存的 50%-70%
innodb_log_buffer_size = 128M
key_buffer_size = 256M
query_cache_size = 0
query_cache_type = 0
# 连接配置
max_connections = 2000
max_connect_errors = 10000
wait_timeout = 600
interactive_timeout = 600
# InnoDB 配置
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2 # 生产环境建议设置为 2
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_doublewrite = 1
innodb_thread_concurrency = 0
# 日志配置
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 0
# 其他配置
skip-name-resolve
lower_case_table_names = 1
索引设计原则:
示例:
-- 创建复合索引
CREATE INDEX idx_user_name_email ON sys_user(username, email);
-- 重建索引
ALTER TABLE sys_user ENGINE=InnoDB;
-- 分析表
ANALYZE TABLE sys_user;
优化建议:
示例:
-- 不好的查询
SELECT * FROM sys_user WHERE DATE(create_time) = '2023-01-01';
-- 优化后的查询
SELECT id, username, email FROM sys_user WHERE create_time BETWEEN '2023-01-01 00:00:00' AND '2023-01-01 23:59:59';
当数据量达到一定规模时,建议考虑分库分表:
分表策略:
核心配置项:
# /etc/redis.conf
# 基础配置
bind 0.0.0.0
protected-mode yes
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
logfile /var/log/redis/redis.log
# 内存配置
maxmemory 6G # 建议为服务器内存的 50%-70%
maxmemory-policy allkeys-lru # 内存不足时的淘汰策略
# 持久化配置
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # 生产环境建议设置为 everysec
# 连接配置
timeout 300
maxclients 10000
# 其他配置
tcp-keepalive 300
优化建议:
缓存雪崩解决方案:
缓存穿透解决方案:
推荐使用 Prometheus + Grafana 搭建监控系统:
日志配置建议:
全量备份:
# 使用 mysqldump 进行全量备份
mysqldump -u root -p --all-databases --single-transaction --routines --triggers --events > /backup/mysql/full_backup_$(date +%Y%m%d_%H%M%S).sql
# 使用 xtrabackup 进行全量备份
xtrabackup --backup --target-dir=/backup/mysql/full_backup_$(date +%Y%m%d_%H%M%S)
增量备份:
# 使用 xtrabackup 进行增量备份
xtrabackup --backup --target-dir=/backup/mysql/incremental_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/backup/mysql/full_backup_20230101_000000
定时备份脚本:
cat > /usr/local/bin/mysql_backup.sh << EOF
#!/bin/bash
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
FULL_BACKUP_DIR="$BACKUP_DIR/full_$DATE"
# 创建备份目录
mkdir -p $FULL_BACKUP_DIR
# 执行全量备份
mysqldump -u root -p"password" --all-databases --single-transaction --routines --triggers --events > $FULL_BACKUP_DIR/full_backup.sql
# 压缩备份文件
tar -czf $BACKUP_DIR/full_backup_$DATE.tar.gz -C $BACKUP_DIR full_$DATE
# 删除临时目录
rm -rf $FULL_BACKUP_DIR
# 删除 7 天前的备份
find $BACKUP_DIR -name "full_backup_*.tar.gz" -mtime +7 -delete
EOF
# 添加到定时任务
chmod +x /usr/local/bin/mysql_backup.sh
echo "0 2 * * * /usr/local/bin/mysql_backup.sh" >> /var/spool/cron/root
示例:
# 备份应用配置和数据
BACKUP_DIR="/backup/app"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR/$DATE
# 备份配置文件
cp -r /opt/tagtag/backend/config $BACKUP_DIR/$DATE/
# 备份日志(可选)
cp -r /opt/tagtag/backend/logs $BACKUP_DIR/$DATE/
# 备份静态资源
cp -r /usr/share/nginx/html/tagtag $BACKUP_DIR/$DATE/
# 压缩备份文件
tar -czf $BACKUP_DIR/app_backup_$DATE.tar.gz -C $BACKUP_DIR $DATE
# 删除临时目录
rm -rf $BACKUP_DIR/$DATE
# 删除 7 天前的备份
find $BACKUP_DIR -name "app_backup_*.tar.gz" -mtime +7 -delete
JMeter 测试示例:
问题:应用启动后立即退出
解决方案:
# 查看日志
cat /opt/tagtag/backend/logs/application.log
# 检查端口占用
netstat -tlnp | grep 8080
# 检查数据库连接
telnet mysql-server 3306
# 检查 Redis 连接
telnet redis-server 6379
问题:应用无法连接到数据库
解决方案:
# 检查数据库服务状态
systemctl status mysqld
# 检查数据库用户权限
mysql -u root -p -e "SHOW GRANTS FOR 'tagtag'@'%';"
# 检查防火墙设置
firewall-cmd --list-ports
# 检查 SELinux 设置
getenforce
问题:访问前端页面显示 404 或空白页
解决方案:
# 检查 Nginx 配置
nginx -t
# 检查 Nginx 日志
cat /var/log/nginx/tagtag.error.log
# 检查静态文件权限
ls -la /usr/share/nginx/html/tagtag/
# 检查前端路由配置
# 确保 Nginx 配置了 try_files $uri $uri/ /index.html;
生产环境部署是一个复杂的过程,需要考虑服务器配置、应用部署、数据库优化、安全配置、监控日志和备份恢复等多个方面。本文档提供了 Tagtag Starter 项目在生产环境部署的详细指南,希望能帮助您顺利完成部署工作。
在实际部署过程中,建议根据您的业务需求和服务器资源情况,灵活调整配置参数,确保系统的高性能、高可用性和高安全性。