一键式压测:用 Bash + AWS CLI + K6 + 自定义 AMI 自动化你的性能测试流程
想要跑一次全面的性能压测,却还要手动配置环境、部署脚本、收集结果?不如一键搞定。
本文将分享如何用一个 Bash 脚本,结合 AWS CLI 与 K6,自定义 AMI 自动完成以下压测流程:
- 启动预置 K6 的 EC2 实例
- 初始化 DynamoDB 表
- 上传 K6 测试脚本
- 远程执行压测(输出 HTML 报告)
- 下载压测结果
- 销毁测试资源
🧰 使用到的工具
- AWS CLI:资源管理
- Bash 脚本:串联所有逻辑
- K6:负载测试
- 自定义 AMI:预装 K6 与依赖
- SSM:远程命令执行(无需 SSH)
- S3:脚本与测试结果传输
- jq:辅助解析 AWS CLI 返回结果
📦 目录结构(简单)
bash
loadtest.sh # 主 Bash 脚本
k6/
├── test-api.js # 示例压测脚本
🚀 主 Bash 脚本:loadtest.sh
bash
#!/bin/bash
set -e
### === 配置 === ###
AWS_PROFILE="default"
AWS_REGION="us-west-2"
AMI_ID="ami-0a1b2c3d4e5f6g7h8" # 预装了 k6 + nodejs + reporters 的 AMI
INSTANCE_TYPE="t3.medium"
KEY_NAME="loadtest-key"
SECURITY_GROUP_ID="sg-xxxxxxxx"
INSTANCE_NAME="k6-loadtest"
TEMP_BUCKET="k6-loadtest-bucket-$(date +%s)"
DYNAMO_TABLE="TestData"
K6_SCRIPT="test-api.js"
REPORT_NAME="report.html"
SSM_ROLE="AmazonEC2RoleforSSM"
### === 步骤 1:创建 S3 bucket === ###
echo "Creating temporary S3 bucket: $TEMP_BUCKET"
aws s3 mb s3://$TEMP_BUCKET --region $AWS_REGION
### === 步骤 2:上传 K6 脚本到 S3 === ###
echo "Uploading K6 script..."
aws s3 cp ./k6/$K6_SCRIPT s3://$TEMP_BUCKET/ --region $AWS_REGION
### === 步骤 3:创建 DynamoDB 表 === ###
echo "Resetting DynamoDB table..."
aws dynamodb delete-table --table-name $DYNAMO_TABLE --region $AWS_REGION || true
aws dynamodb wait table-not-exists --table-name $DYNAMO_TABLE --region $AWS_REGION
aws dynamodb create-table \
--table-name $DYNAMO_TABLE \
--attribute-definitions AttributeName=Id,AttributeType=S \
--key-schema AttributeName=Id,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--region $AWS_REGION
aws dynamodb wait table-exists --table-name $DYNAMO_TABLE --region $AWS_REGION
### === 步骤 4:启动 EC2 === ###
echo "Launching EC2 instance..."
INSTANCE_ID=$(aws ec2 run-instances \
--image-id $AMI_ID \
--instance-type $INSTANCE_TYPE \
--key-name $KEY_NAME \
--security-group-ids $SECURITY_GROUP_ID \
--iam-instance-profile Name=$SSM_ROLE \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=$INSTANCE_NAME}]" \
--query "Instances[0].InstanceId" \
--output text \
--region $AWS_REGION)
echo "Instance ID: $INSTANCE_ID"
aws ec2 wait instance-status-ok --instance-ids $INSTANCE_ID --region $AWS_REGION
### === 步骤 5:远程执行压测 === ###
echo "Running K6 test on EC2..."
RUN_COMMAND=$(cat <<EOF
cd /home/ec2-user
aws s3 cp s3://$TEMP_BUCKET/$K6_SCRIPT .
k6 run $K6_SCRIPT --out html=$REPORT_NAME
aws s3 cp $REPORT_NAME s3://$TEMP_BUCKET/
EOF
)
aws ssm send-command \
--document-name "AWS-RunShellScript" \
--targets "Key=tag:Name,Values=$INSTANCE_NAME" \
--parameters commands="$RUN_COMMAND" \
--region $AWS_REGION \
--comment "Run K6 performance test"
echo "Waiting for test to complete..."
sleep 60
### === 步骤 6:下载报告 === ###
echo "Downloading test report..."
mkdir -p results
aws s3 cp s3://$TEMP_BUCKET/$REPORT_NAME ./results/$REPORT_NAME --region $AWS_REGION
### === 步骤 7:清理资源 === ###
echo "Cleaning up resources..."
aws ec2 terminate-instances --instance-ids $INSTANCE_ID --region $AWS_REGION
aws ec2 wait instance-terminated --instance-ids $INSTANCE_ID --region $AWS_REGION
aws dynamodb delete-table --table-name $DYNAMO_TABLE --region $AWS_REGION
aws s3 rb s3://$TEMP_BUCKET --force --region $AWS_REGION
echo "✅ All done! Report saved at ./results/$REPORT_NAME"
📜 示例 K6 脚本:k6/test-api.js
javascript
import http from 'k6/http';
import { check } from 'k6';
import { htmlReport } from 'https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js';
export const options = {
vus: 50,
duration: '1m',
};
export default function () {
const res = http.get('https://your-api.com/endpoint');
check(res, {
'status is 200': (r) => r.status === 200,
});
}
export function handleSummary(data) {
return {
'report.html': htmlReport(data),
};
}
✅ 总结
这个一键 Bash 脚本压测方案带来:
- 无手动配置:所有依赖打包进 AMI
- 可重复压测:干净环境 + 自动上传下载
- 结构清晰:便于集成 CI/CD
- 结果可视化:HTML 报告一目了然
只需:
bash
bash loadtest.sh
即可触发完整流程!