Files
xingrin/backend/scripts/performance/start_performance_test.sh

426 lines
14 KiB
Bash
Raw Normal View History

2025-12-12 18:04:57 +08:00
#!/bin/bash
# 性能测试快速启动脚本
# 用法:./start_performance_test.sh
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
echo "========================================"
echo " PostgreSQL 性能测试工具"
echo "========================================"
echo ""
# 加载 .env 文件中的数据库配置
if [ -f "$PROJECT_DIR/.env" ]; then
echo "加载数据库配置..."
export PGHOST=$(grep "^DB_HOST=" "$PROJECT_DIR/.env" | cut -d '=' -f2)
export PGPORT=$(grep "^DB_PORT=" "$PROJECT_DIR/.env" | cut -d '=' -f2)
export PGUSER=$(grep "^DB_USER=" "$PROJECT_DIR/.env" | cut -d '=' -f2)
export PGPASSWORD=$(grep "^DB_PASSWORD=" "$PROJECT_DIR/.env" | cut -d '=' -f2)
export PGDATABASE=$(grep "^DB_NAME=" "$PROJECT_DIR/.env" | cut -d '=' -f2)
echo " 主机: $PGHOST:$PGPORT"
echo " 用户: $PGUSER"
echo " 数据库: $PGDATABASE"
else
echo "[WARN] 未找到 .env 文件"
fi
echo ""
# 检查 PostgreSQL 连接
echo "检查数据库连接..."
cd "$PROJECT_DIR"
if ! source "$PROJECT_DIR/../.venv/bin/activate" && python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from django.db import connection
try:
with connection.cursor() as cursor:
cursor.execute('SELECT 1')
print('✓ 数据库连接正常')
except Exception as e:
print(f'[ERROR] 数据库连接失败: {e}')
exit(1)
" > /dev/null 2>&1; then
echo "[ERROR] 无法连接到数据库 $PGDATABASE"
echo ""
echo "请检查:"
echo " 1. VPS 防火墙是否开放 5432 端口"
echo " 2. PostgreSQL 的 pg_hba.conf 是否允许远程连接"
echo " 3. .env 文件中的数据库配置是否正确"
echo " 4. Django 设置是否正确"
echo ""
echo "手动测试连接:"
echo " cd $PROJECT_DIR && source $PROJECT_DIR/../.venv/bin/activate && python manage.py dbshell"
exit 1
fi
echo "✓ 数据库连接正常"
echo ""
# 菜单选择
echo "请选择操作:"
echo " 1) 测试批次大小(推荐先执行)"
echo " 2) 生成 1 万条测试数据"
echo " 3) 生成 10 万条测试数据"
echo " 4) 生成 100 万条测试数据"
echo " 5) 启动实时监控(独立运行)"
echo " 6) 查看测试前基准数据"
echo " 7) 查看测试后统计数据"
echo " 8) 完整测试流程(自动化)"
echo " 0) 退出"
echo ""
read -p "请输入选项 (0-8): " choice
case $choice in
1)
echo ""
echo "开始测试批次大小..."
cd "$PROJECT_DIR"
source "$PROJECT_DIR/../.venv/bin/activate"
# 自动创建测试目标
echo "创建测试目标..."
python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from apps.targets.models import Target, Organization
# 创建默认组织
org, _ = Organization.objects.get_or_create(
name='测试组织',
defaults={'description': '性能测试专用组织'}
)
# 创建测试目标
for i in range(1, 4):
target_name = f'test{i}.com'
target, created = Target.objects.get_or_create(
name=target_name
)
if created:
# 将目标添加到组织
org.targets.add(target)
print(f'✓ 创建目标: {target_name}')
else:
print(f'✓ 目标已存在: {target_name}')
"
echo ""
python manage.py generate_test_data --target test1.com --count 10000 --test-batch-sizes
;;
2)
echo ""
echo "使用默认批次大小: 5000"
echo "开始生成 1 万条数据..."
cd "$PROJECT_DIR"
source "$PROJECT_DIR/../.venv/bin/activate"
# 自动创建测试目标
echo "创建测试目标..."
python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from apps.targets.models import Target, Organization
# 创建默认组织
org, _ = Organization.objects.get_or_create(
name='测试组织',
defaults={'description': '性能测试专用组织'}
)
# 创建测试目标
for i in range(1, 4):
target_name = f'test{i}.com'
target, created = Target.objects.get_or_create(
name=target_name
)
if created:
# 将目标添加到组织
org.targets.add(target)
print(f'✓ 创建目标: {target_name}')
else:
print(f'✓ 目标已存在: {target_name}')
"
echo ""
python manage.py generate_test_data \
--target test1.com \
--count 10000 \
--batch-size 5000 \
--benchmark
;;
3)
echo ""
echo "使用默认批次大小: 5000"
echo "开始生成 10 万条数据..."
cd "$PROJECT_DIR"
source "$PROJECT_DIR/../.venv/bin/activate"
# 自动创建测试目标
echo "创建测试目标..."
python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from apps.targets.models import Target, Organization
# 创建默认组织
org, _ = Organization.objects.get_or_create(
name='测试组织',
defaults={'description': '性能测试专用组织'}
)
# 创建测试目标
for i in range(1, 4):
target_name = f'test{i}.com'
target, created = Target.objects.get_or_create(
name=target_name
)
if created:
# 将目标添加到组织
org.targets.add(target)
print(f'✓ 创建目标: {target_name}')
else:
print(f'✓ 目标已存在: {target_name}')
"
echo ""
python manage.py generate_test_data \
--target test2.com \
--count 100000 \
--batch-size 5000 \
--benchmark
;;
4)
echo ""
echo "使用默认批次大小: 5000"
echo "[WARN] 警告:这将生成 100 万条数据,可能需要 2-4 小时"
read -p "确认继续? (y/N): " confirm
if [[ $confirm == [yY] ]]; then
echo ""
echo "开始生成 100 万条数据..."
cd "$PROJECT_DIR"
source "$PROJECT_DIR/../.venv/bin/activate"
# 自动创建测试目标
echo "创建测试目标..."
python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from apps.targets.models import Target, Organization
# 创建默认组织
org, _ = Organization.objects.get_or_create(
name='测试组织',
defaults={'description': '性能测试专用组织'}
)
# 创建测试目标
for i in range(1, 4):
target_name = f'test{i}.com'
target, created = Target.objects.get_or_create(
name=target_name
)
if created:
# 将目标添加到组织
org.targets.add(target)
print(f'✓ 创建目标: {target_name}')
else:
print(f'✓ 目标已存在: {target_name}')
"
echo ""
python manage.py generate_test_data \
--target test3.com \
--count 1000000 \
--batch-size 5000 \
--benchmark
fi
;;
5)
echo ""
read -p "刷新间隔(秒,推荐 2-5: " interval
interval=${interval:-2}
echo ""
echo "启动 PostgreSQL 实时监控..."
echo "按 Ctrl+C 停止监控"
sleep 2
"$SCRIPT_DIR/monitor_pg_performance.sh" xingrin "$interval"
;;
6)
echo ""
echo "记录测试前基准数据..."
mkdir -p "$PROJECT_DIR/logs"
psql -d "$PGDATABASE" -f "$SCRIPT_DIR/pg_stats_before_test.sql" > "$PROJECT_DIR/logs/stats_before.txt"
echo "✓ 已保存到: $PROJECT_DIR/logs/stats_before.txt"
echo ""
read -p "是否查看内容? (y/N): " view
if [[ $view == [yY] ]]; then
less "$PROJECT_DIR/logs/stats_before.txt"
fi
;;
7)
echo ""
echo "记录测试后统计数据..."
mkdir -p "$PROJECT_DIR/logs"
psql -d "$PGDATABASE" -f "$SCRIPT_DIR/pg_stats_after_test.sql" > "$PROJECT_DIR/logs/stats_after.txt"
echo "✓ 已保存到: $PROJECT_DIR/logs/stats_after.txt"
echo ""
read -p "是否对比测试前后? (y/N): " compare
if [[ $compare == [yY] ]] && [ -f "$PROJECT_DIR/logs/stats_before.txt" ]; then
echo ""
echo "差异对比:"
diff "$PROJECT_DIR/logs/stats_before.txt" "$PROJECT_DIR/logs/stats_after.txt" || true
fi
;;
8)
echo ""
echo "========================================"
echo " 完整自动化测试流程"
echo "========================================"
echo ""
echo "步骤 1创建测试目标"
cd "$PROJECT_DIR"
source "$PROJECT_DIR/../.venv/bin/activate"
python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from apps.targets.models import Target, Organization
# 创建默认组织
org, _ = Organization.objects.get_or_create(
name='测试组织',
defaults={'description': '性能测试专用组织'}
)
# 创建测试目标
for i in range(1, 4):
target_name = f'test{i}.com'
target, created = Target.objects.get_or_create(
name=target_name
)
if created:
# 将目标添加到组织
org.targets.add(target)
print(f'✓ 创建目标: {target_name}')
else:
print(f'✓ 目标已存在: {target_name}')
"
echo "✓ 完成"
echo ""
echo "步骤 2记录测试前基准数据"
mkdir -p "$PROJECT_DIR/logs"
psql -d "$PGDATABASE" -f "$SCRIPT_DIR/pg_stats_before_test.sql" > "$PROJECT_DIR/logs/stats_before.txt" 2>&1
echo "✓ 完成"
echo ""
echo "步骤 3测试批次大小"
python manage.py generate_test_data --target test1.com --count 10000 --test-batch-sizes | tee "$PROJECT_DIR/logs/batch_size_test.txt"
echo ""
# 自动提取最优批次大小如果没有找到则使用默认值5000
optimal_batch=$(grep "推荐批次大小:" "$PROJECT_DIR/logs/batch_size_test.txt" | awk '{print $2}' || echo "5000")
optimal_batch=${optimal_batch:-5000}
echo "✓ 自动选择最优批次: $optimal_batch"
echo ""
echo "步骤 4生成 10 万条数据"
python manage.py generate_test_data \
--target test3.com \
--count 100000 \
--batch-size "$optimal_batch" \
--benchmark | tee "$PROJECT_DIR/logs/test_results.txt"
echo ""
echo "步骤 5记录测试后统计"
psql -d "$PGDATABASE" -f "$SCRIPT_DIR/pg_stats_after_test.sql" > "$PROJECT_DIR/logs/stats_after.txt" 2>&1
echo "✓ 完成"
echo ""
# 生成性能报告
echo "步骤 6生成性能报告"
report_file="$PROJECT_DIR/logs/performance_report.txt"
echo "========================================" > "$report_file"
echo " XingRin 性能测试报告" >> "$report_file"
echo "========================================" >> "$report_file"
echo "" >> "$report_file"
echo "测试时间: $(date '+%Y-%m-%d %H:%M:%S')" >> "$report_file"
echo "数据库: $PGHOST:$PGPORT/$PGDATABASE" >> "$report_file"
echo "最优批次: $optimal_batch" >> "$report_file"
echo "" >> "$report_file"
# 提取批次测试结果
echo "========================================" >> "$report_file"
echo " 批次大小性能对比" >> "$report_file"
echo "========================================" >> "$report_file"
grep -A 10 "批次大小对比结果" "$PROJECT_DIR/logs/batch_size_test.txt" | tail -n +4 >> "$report_file"
echo "" >> "$report_file"
# 提取详细测试结果
echo "========================================" >> "$report_file"
echo " 10万条数据生成性能" >> "$report_file"
echo "========================================" >> "$report_file"
grep "性能测试报告" -A 20 "$PROJECT_DIR/logs/test_results.txt" | tail -n +3 >> "$report_file"
echo "" >> "$report_file"
# 提取总耗时
total_time=$(grep "总耗时:" "$PROJECT_DIR/logs/test_results.txt" | head -1)
echo "========================================" >> "$report_file"
echo " 总体性能" >> "$report_file"
echo "========================================" >> "$report_file"
echo "$total_time" >> "$report_file"
echo "" >> "$report_file"
echo "========================================" >> "$report_file"
echo " 测试文件" >> "$report_file"
echo "========================================" >> "$report_file"
echo "- 测试前基准: logs/stats_before.txt" >> "$report_file"
echo "- 批次测试: logs/batch_size_test.txt" >> "$report_file"
echo "- 性能结果: logs/test_results.txt" >> "$report_file"
echo "- 测试后统计: logs/stats_after.txt" >> "$report_file"
echo "- 性能报告: logs/performance_report.txt" >> "$report_file"
echo "" >> "$report_file"
echo "✓ 性能报告已生成"
echo ""
echo "========================================"
echo " ✓ 自动化测试完成!"
echo "========================================"
echo ""
# 显示性能报告
cat "$report_file"
echo ""
echo "详细报告已保存到: $report_file"
echo ""
;;
0)
echo "退出"
exit 0
;;
*)
echo "无效选项"
exit 1
;;
esac
echo ""
echo "完成!"