QAUP_Management/deploy/docker/performance-tuning.sh

622 lines
16 KiB
Bash
Executable File
Raw Permalink 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.

#!/bin/bash
# QAUP 性能优化脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_message() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}
# 获取系统信息
get_system_info() {
local total_mem=$(free -m | awk 'NR==2{print $2}')
local cpu_cores=$(nproc)
local total_disk=$(df -BG . | awk 'NR==2 {print $2}' | sed 's/G//')
echo "系统信息:"
echo " CPU 核心数: $cpu_cores"
echo " 总内存: ${total_mem}MB"
echo " 可用磁盘: ${total_disk}GB"
echo ""
# 导出变量供其他函数使用
export TOTAL_MEM=$total_mem
export CPU_CORES=$cpu_cores
export TOTAL_DISK=$total_disk
}
# 优化 JVM 参数
optimize_jvm() {
print_message $BLUE "优化 JVM 参数..."
local heap_size
local metaspace_size
# 根据系统内存计算 JVM 参数
if [ $TOTAL_MEM -ge 8192 ]; then
# 8GB+ 内存
heap_size="4g"
metaspace_size="512m"
elif [ $TOTAL_MEM -ge 4096 ]; then
# 4-8GB 内存
heap_size="2g"
metaspace_size="256m"
else
# 4GB 以下内存
heap_size="1g"
metaspace_size="128m"
fi
# 生成优化的 JVM 参数
local jvm_opts="-Dname=qaup-admin.jar"
jvm_opts="$jvm_opts -Duser.timezone=Asia/Shanghai"
jvm_opts="$jvm_opts -server"
jvm_opts="$jvm_opts -Xms${heap_size} -Xmx${heap_size}"
jvm_opts="$jvm_opts -XX:MetaspaceSize=${metaspace_size} -XX:MaxMetaspaceSize=${metaspace_size}"
# GC 优化
if [ $CPU_CORES -ge 4 ]; then
# 多核使用 G1GC
jvm_opts="$jvm_opts -XX:+UseG1GC"
jvm_opts="$jvm_opts -XX:G1HeapRegionSize=16m"
jvm_opts="$jvm_opts -XX:MaxGCPauseMillis=200"
jvm_opts="$jvm_opts -XX:+UseStringDeduplication"
else
# 少核使用 Parallel GC
jvm_opts="$jvm_opts -XX:+UseParallelGC"
jvm_opts="$jvm_opts -XX:+UseParallelOldGC"
fi
# 性能监控和调试
jvm_opts="$jvm_opts -XX:+HeapDumpOnOutOfMemoryError"
jvm_opts="$jvm_opts -XX:HeapDumpPath=/app/logs/"
jvm_opts="$jvm_opts -XX:+PrintGCDetails"
jvm_opts="$jvm_opts -XX:+PrintGCTimeStamps"
jvm_opts="$jvm_opts -Xloggc:/app/logs/gc.log"
# 更新环境文件
if [ -f "$PROJECT_ROOT/.env" ]; then
# 备份原文件
cp "$PROJECT_ROOT/.env" "$PROJECT_ROOT/.env.backup.$(date +%Y%m%d_%H%M%S)"
# 更新 JVM_OPTS
if grep -q "^JVM_OPTS=" "$PROJECT_ROOT/.env"; then
sed -i "s|^JVM_OPTS=.*|JVM_OPTS=$jvm_opts|" "$PROJECT_ROOT/.env"
else
echo "JVM_OPTS=$jvm_opts" >> "$PROJECT_ROOT/.env"
fi
print_message $GREEN "✓ JVM 参数已优化"
echo " 堆内存: $heap_size"
echo " 元空间: $metaspace_size"
echo " GC算法: $(echo $jvm_opts | grep -o 'XX:+Use[A-Za-z0-9]*GC')"
else
print_message $RED "✗ 环境文件不存在: $PROJECT_ROOT/.env"
fi
}
# 优化数据库配置
optimize_database() {
print_message $BLUE "优化数据库配置..."
local shared_buffers
local effective_cache_size
local work_mem
local maintenance_work_mem
local max_connections
# 根据系统内存计算数据库参数
if [ $TOTAL_MEM -ge 8192 ]; then
# 8GB+ 内存
shared_buffers="2GB"
effective_cache_size="6GB"
work_mem="16MB"
maintenance_work_mem="256MB"
max_connections="200"
elif [ $TOTAL_MEM -ge 4096 ]; then
# 4-8GB 内存
shared_buffers="1GB"
effective_cache_size="3GB"
work_mem="8MB"
maintenance_work_mem="128MB"
max_connections="150"
else
# 4GB 以下内存
shared_buffers="512MB"
effective_cache_size="1536MB"
work_mem="4MB"
maintenance_work_mem="64MB"
max_connections="100"
fi
# 生成优化的 PostgreSQL 配置
cat > "$PROJECT_ROOT/docker/postgres/postgresql-optimized.conf" << EOF
# PostgreSQL 性能优化配置
# 自动生成于: $(date)
# 连接设置
listen_addresses = '*'
port = 5432
max_connections = $max_connections
superuser_reserved_connections = 3
# 内存设置
shared_buffers = $shared_buffers
effective_cache_size = $effective_cache_size
work_mem = $work_mem
maintenance_work_mem = $maintenance_work_mem
# 检查点设置
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
# 查询规划器设置
random_page_cost = 1.1
effective_io_concurrency = $([ $TOTAL_DISK -gt 100 ] && echo "200" || echo "100")
# 写前日志设置
wal_level = replica
max_wal_size = 2GB
min_wal_size = 80MB
# 自动清理设置
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 1min
autovacuum_vacuum_threshold = 50
autovacuum_analyze_threshold = 50
# 日志设置
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 1000
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
# 时区设置
timezone = 'Asia/Shanghai'
log_timezone = 'Asia/Shanghai'
# 字符集设置
lc_messages = 'en_US.UTF-8'
lc_monetary = 'en_US.UTF-8'
lc_numeric = 'en_US.UTF-8'
lc_time = 'en_US.UTF-8'
# 默认文本搜索配置
default_text_search_config = 'pg_catalog.english'
# 并发设置
max_worker_processes = $CPU_CORES
max_parallel_workers_per_gather = $([ $CPU_CORES -gt 2 ] && echo "2" || echo "1")
max_parallel_workers = $CPU_CORES
EOF
print_message $GREEN "✓ 数据库配置已优化"
echo " 共享缓冲区: $shared_buffers"
echo " 有效缓存: $effective_cache_size"
echo " 工作内存: $work_mem"
echo " 最大连接数: $max_connections"
}
# 优化 Nginx 配置
optimize_nginx() {
print_message $BLUE "优化 Nginx 配置..."
# 生成优化的 Nginx 配置
cat > "$PROJECT_ROOT/docker/nginx/nginx-optimized.conf" << EOF
# Nginx 性能优化配置
# 自动生成于: $(date)
user nginx;
worker_processes $CPU_CORES;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# 优化事件处理
events {
worker_connections $([ $TOTAL_MEM -gt 4096 ] && echo "2048" || echo "1024");
use epoll;
multi_accept on;
worker_rlimit_nofile 65535;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for" '
'rt=\$request_time uct="\$upstream_connect_time" '
'uht="\$upstream_header_time" urt="\$upstream_response_time"';
access_log /var/log/nginx/access.log main;
# 基本设置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
types_hash_max_size 2048;
server_tokens off;
# 缓冲区设置
client_body_buffer_size 128k;
client_max_body_size 50m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;
# 超时设置
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# 缓存设置
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 包含虚拟主机配置
include /etc/nginx/conf.d/*.conf;
}
EOF
print_message $GREEN "✓ Nginx 配置已优化"
echo " 工作进程数: $CPU_CORES"
echo " 连接数: $([ $TOTAL_MEM -gt 4096 ] && echo "2048" || echo "1024")"
echo " 缓冲区: 优化完成"
}
# 优化 Redis 配置
optimize_redis() {
print_message $BLUE "优化 Redis 配置..."
local maxmemory
# 根据系统内存计算 Redis 内存限制
if [ $TOTAL_MEM -ge 8192 ]; then
maxmemory="1gb"
elif [ $TOTAL_MEM -ge 4096 ]; then
maxmemory="512mb"
else
maxmemory="256mb"
fi
# 生成优化的 Redis 配置
cat > "$PROJECT_ROOT/docker/redis/redis-optimized.conf" << EOF
# Redis 性能优化配置
# 自动生成于: $(date)
# 内存设置
maxmemory $maxmemory
maxmemory-policy allkeys-lru
# 持久化设置
save 900 1
save 300 10
save 60 10000
# AOF 设置
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 网络设置
tcp-keepalive 300
timeout 0
# 客户端设置
maxclients 10000
# 慢日志设置
slowlog-log-slower-than 10000
slowlog-max-len 128
# 其他优化
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
EOF
print_message $GREEN "✓ Redis 配置已优化"
echo " 最大内存: $maxmemory"
echo " 淘汰策略: allkeys-lru"
echo " 持久化: AOF + RDB"
}
# 优化系统参数
optimize_system() {
print_message $BLUE "优化系统参数..."
# 检查是否有 root 权限
if [ "$EUID" -ne 0 ]; then
print_message $YELLOW "⚠ 需要 root 权限来优化系统参数"
print_message $YELLOW "请手动执行以下命令或使用 sudo 运行此脚本:"
echo ""
echo "# 网络优化"
echo "echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf"
echo "echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf"
echo "echo 'net.ipv4.tcp_max_syn_backlog = 65535' >> /etc/sysctl.conf"
echo "echo 'net.ipv4.tcp_fin_timeout = 10' >> /etc/sysctl.conf"
echo "echo 'net.ipv4.tcp_tw_reuse = 1' >> /etc/sysctl.conf"
echo "echo 'net.ipv4.tcp_keepalive_time = 600' >> /etc/sysctl.conf"
echo ""
echo "# 文件描述符限制"
echo "echo '* soft nofile 65535' >> /etc/security/limits.conf"
echo "echo '* hard nofile 65535' >> /etc/security/limits.conf"
echo ""
echo "# 应用生效"
echo "sysctl -p"
return
fi
# 网络参数优化
cat >> /etc/sysctl.conf << EOF
# QAUP 系统优化参数
# 添加时间: $(date)
# 网络优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
# 虚拟内存优化
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
EOF
# 文件描述符限制
cat >> /etc/security/limits.conf << EOF
# QAUP 系统文件描述符限制
# 添加时间: $(date)
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
EOF
# 应用系统参数
sysctl -p
print_message $GREEN "✓ 系统参数已优化"
}
# 创建性能监控脚本
create_performance_monitor() {
print_message $BLUE "创建性能监控脚本..."
cat > "$PROJECT_ROOT/docker/performance-monitor.sh" << 'EOF'
#!/bin/bash
# QAUP 性能监控脚本
MONITOR_LOG="./logs/performance-$(date +%Y%m%d).log"
# 记录性能数据
log_performance() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
{
echo "[$timestamp] 性能监控数据"
echo "================================"
# 系统资源
echo "系统负载: $(uptime | awk -F'load average:' '{print $2}')"
echo "内存使用: $(free | awk 'NR==2{printf "%.2f%%", $3*100/$2}')"
echo "磁盘使用: $(df -h . | awk 'NR==2{print $5}')"
# 容器资源
echo ""
echo "容器资源使用:"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"
# 应用性能
echo ""
echo "应用响应时间:"
local app_time=$(curl -o /dev/null -s -w '%{time_total}' http://localhost:8080/actuator/health 2>/dev/null || echo "N/A")
local nginx_time=$(curl -o /dev/null -s -w '%{time_total}' http://localhost/health 2>/dev/null || echo "N/A")
echo "应用健康检查: ${app_time}s"
echo "Nginx健康检查: ${nginx_time}s"
# 数据库性能
echo ""
echo "数据库连接数:"
local db_connections=$(docker exec qaup-postgres psql -U postgres -d qaup -t -c "SELECT count(*) FROM pg_stat_activity;" 2>/dev/null | xargs || echo "N/A")
echo "活跃连接: $db_connections"
echo "================================"
echo ""
} >> "$MONITOR_LOG"
}
# 主循环
while true; do
log_performance
sleep 300 # 每5分钟记录一次
done
EOF
chmod +x "$PROJECT_ROOT/docker/performance-monitor.sh"
print_message $GREEN "✓ 性能监控脚本已创建"
}
# 应用所有优化
apply_all_optimizations() {
print_message $GREEN "开始应用所有性能优化..."
echo ""
get_system_info
optimize_jvm
echo ""
optimize_database
echo ""
optimize_nginx
echo ""
optimize_redis
echo ""
optimize_system
echo ""
create_performance_monitor
echo ""
print_message $GREEN "========================================="
print_message $GREEN "性能优化完成!"
print_message $GREEN "========================================="
echo ""
print_message $BLUE "优化摘要:"
echo " ✓ JVM 参数已根据系统配置优化"
echo " ✓ 数据库配置已优化"
echo " ✓ Nginx 配置已优化"
echo " ✓ Redis 配置已优化"
echo " ✓ 系统参数已优化(如有权限)"
echo " ✓ 性能监控脚本已创建"
echo ""
print_message $YELLOW "下一步操作:"
echo " 1. 重启服务以应用配置: ./deploy.sh restart"
echo " 2. 启动性能监控: ./docker/performance-monitor.sh &"
echo " 3. 验证优化效果: ./docker/monitor.sh resources"
echo ""
}
# 显示帮助信息
show_help() {
echo "QAUP 性能优化脚本"
echo ""
echo "用法: $0 [命令]"
echo ""
echo "命令:"
echo " all 应用所有优化"
echo " jvm 优化 JVM 参数"
echo " database 优化数据库配置"
echo " nginx 优化 Nginx 配置"
echo " redis 优化 Redis 配置"
echo " system 优化系统参数"
echo " monitor 创建性能监控脚本"
echo ""
echo "示例:"
echo " $0 all # 应用所有优化"
echo " $0 jvm # 仅优化 JVM"
echo " sudo $0 system # 优化系统参数(需要 root"
}
# 主函数
main() {
if [ $# -eq 0 ]; then
show_help
exit 0
fi
local command=$1
# 获取系统信息
get_system_info
case $command in
all)
apply_all_optimizations
;;
jvm)
optimize_jvm
;;
database)
optimize_database
;;
nginx)
optimize_nginx
;;
redis)
optimize_redis
;;
system)
optimize_system
;;
monitor)
create_performance_monitor
;;
help|--help|-h)
show_help
;;
*)
print_message $RED "未知命令: $command"
show_help
exit 1
;;
esac
}
main "$@"