622 lines
16 KiB
Bash
Executable File
622 lines
16 KiB
Bash
Executable File
#!/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 "$@" |