add hardcore_test, load_test, update README with AWS CLI install + test descriptions
This commit is contained in:
+204
@@ -0,0 +1,204 @@
|
||||
#!/bin/bash
|
||||
# load_test.sh — Нагрузочный тест SQS-сервиса
|
||||
# Замеряет: latency, throughput, параллельную работу
|
||||
# Требования: curl, bash
|
||||
# Запуск: bash load_test.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
# КОНФИГУРАЦИЯ — измените под свой тенант
|
||||
# ═══════════════════════════════════════════
|
||||
SQS_ENDPOINT="https://sqs.kube5s.ru/sqs/test001"
|
||||
AUTH="SQSAK-test001-ae4dc8:J8mElXq8Nwww8iFRtGJCm8KfxM9XSTluTqS2A67xsEE"
|
||||
VER="2012-11-05"
|
||||
TS=$(date +%s)
|
||||
TMPDIR=$(mktemp -d /tmp/sqs-load-XXXXX)
|
||||
|
||||
MESSAGES=50 # Сообщений в последовательном тесте
|
||||
WORKERS=5 # Параллельных воркеров
|
||||
MSGS_PER_WORKER=20 # Сообщений на воркер
|
||||
STRESS_SEC=30 # Секунд стресс-теста
|
||||
|
||||
ms_now() { date +%s%N | cut -b1-13; }
|
||||
|
||||
call() {
|
||||
curl -s --max-time 30 -u "$AUTH" "${SQS_ENDPOINT}?${1}&Version=${VER}" 2>&1
|
||||
}
|
||||
|
||||
echo "╔═══════════════════════════════════════════════════════╗"
|
||||
echo "║ SQS Load Test — $(date '+%Y-%m-%d %H:%M:%S') ║"
|
||||
echo "║ Endpoint: ${SQS_ENDPOINT} ║"
|
||||
echo "║ Параметры: ${MESSAGES} seq, ${WORKERS}×${MSGS_PER_WORKER} par, ${STRESS_SEC}s stress ║"
|
||||
echo "╚═══════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 1. Latency (20 замеров) ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
QL="lq-lat-${TS}"
|
||||
call "Action=CreateQueue&QueueName=${QL}" >/dev/null
|
||||
|
||||
TIMES=()
|
||||
for i in $(seq 1 20); do
|
||||
T1=$(ms_now)
|
||||
call "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QL}&MessageBody=lat-${i}" >/dev/null
|
||||
T2=$(ms_now)
|
||||
TIMES+=( $((T2 - T1)) )
|
||||
done
|
||||
|
||||
SUM=0; MIN=999999; MAX=0
|
||||
for t in "${TIMES[@]}"; do
|
||||
SUM=$((SUM + t))
|
||||
[ "$t" -lt "$MIN" ] && MIN=$t
|
||||
[ "$t" -gt "$MAX" ] && MAX=$t
|
||||
done
|
||||
AVG=$((SUM / ${#TIMES[@]}))
|
||||
echo " SendMessage: avg=${AVG}ms min=${MIN}ms max=${MAX}ms"
|
||||
|
||||
TIMES=()
|
||||
for i in $(seq 1 20); do
|
||||
T1=$(ms_now)
|
||||
call "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QL}&MaxNumberOfMessages=1" >/dev/null
|
||||
T2=$(ms_now)
|
||||
TIMES+=( $((T2 - T1)) )
|
||||
done
|
||||
|
||||
SUM=0; MIN=999999; MAX=0
|
||||
for t in "${TIMES[@]}"; do
|
||||
SUM=$((SUM + t))
|
||||
[ "$t" -lt "$MIN" ] && MIN=$t
|
||||
[ "$t" -gt "$MAX" ] && MAX=$t
|
||||
done
|
||||
AVG=$((SUM / ${#TIMES[@]}))
|
||||
echo " ReceiveMessage: avg=${AVG}ms min=${MIN}ms max=${MAX}ms"
|
||||
|
||||
call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QL}" >/dev/null
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 2. Последовательный throughput (${MESSAGES} сообщений) ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
QS="lq-seq-${TS}"
|
||||
call "Action=CreateQueue&QueueName=${QS}" >/dev/null
|
||||
|
||||
T1=$(ms_now)
|
||||
OK=0; ERR=0
|
||||
for i in $(seq 1 $MESSAGES); do
|
||||
R=$(call "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QS}&MessageBody=seq-${i}")
|
||||
if echo "$R" | grep -q "MessageId"; then OK=$((OK + 1)); else ERR=$((ERR + 1)); fi
|
||||
done
|
||||
T2=$(ms_now)
|
||||
ELAPSED=$((T2 - T1))
|
||||
RPS=$(( OK * 1000 / (ELAPSED + 1) ))
|
||||
echo " Send: ${OK} OK / ${ERR} ERR за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)"
|
||||
|
||||
T1=$(ms_now)
|
||||
GOT=0; EMPTY=0
|
||||
for _ in $(seq 1 $((MESSAGES + 30))); do
|
||||
R=$(call "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QS}&MaxNumberOfMessages=10")
|
||||
C=$(echo "$R" | grep -c "<Message>" || true)
|
||||
if [ "$C" -gt 0 ]; then GOT=$((GOT + C)); else EMPTY=$((EMPTY + 1)); [ "$EMPTY" -ge 3 ] && break; fi
|
||||
[ "$GOT" -ge "$MESSAGES" ] && break
|
||||
done
|
||||
T2=$(ms_now)
|
||||
ELAPSED=$((T2 - T1))
|
||||
RPS=$(( GOT * 1000 / (ELAPSED + 1) ))
|
||||
echo " Recv: ${GOT}/${MESSAGES} за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)"
|
||||
|
||||
call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QS}" >/dev/null
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 3. Параллельная отправка (${WORKERS} × ${MSGS_PER_WORKER}) ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
QP="lq-par-${TS}"
|
||||
call "Action=CreateQueue&QueueName=${QP}" >/dev/null
|
||||
|
||||
worker_send() {
|
||||
local wid=$1; local ok=0
|
||||
for i in $(seq 1 $MSGS_PER_WORKER); do
|
||||
R=$(curl -s --max-time 30 -u "$AUTH" "${SQS_ENDPOINT}?Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QP}&MessageBody=w${wid}-${i}&Version=${VER}" 2>&1)
|
||||
echo "$R" | grep -q "MessageId" && ok=$((ok + 1))
|
||||
done
|
||||
echo "$ok" > "${TMPDIR}/w-${wid}.ok"
|
||||
}
|
||||
|
||||
T1=$(ms_now)
|
||||
for w in $(seq 1 $WORKERS); do worker_send $w & done
|
||||
wait
|
||||
T2=$(ms_now)
|
||||
ELAPSED=$((T2 - T1))
|
||||
|
||||
TOT_OK=0
|
||||
for w in $(seq 1 $WORKERS); do
|
||||
[ -f "${TMPDIR}/w-${w}.ok" ] && TOT_OK=$((TOT_OK + $(cat "${TMPDIR}/w-${w}.ok")))
|
||||
done
|
||||
TOT=$((WORKERS * MSGS_PER_WORKER))
|
||||
RPS=$(( TOT_OK * 1000 / (ELAPSED + 1) ))
|
||||
echo " Send: ${TOT_OK}/${TOT} за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)"
|
||||
|
||||
# Параллельный receive
|
||||
worker_recv() {
|
||||
local wid=$1; local ok=0; local empty=0
|
||||
for _ in $(seq 1 $((MSGS_PER_WORKER + 10))); do
|
||||
R=$(curl -s --max-time 30 -u "$AUTH" "${SQS_ENDPOINT}?Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QP}&MaxNumberOfMessages=10&Version=${VER}" 2>&1)
|
||||
C=$(echo "$R" | grep -c "<Message>" || true)
|
||||
if [ "$C" -gt 0 ]; then ok=$((ok + C)); else empty=$((empty + 1)); [ "$empty" -ge 3 ] && break; fi
|
||||
done
|
||||
echo "$ok" > "${TMPDIR}/r-${wid}.ok"
|
||||
}
|
||||
|
||||
T1=$(ms_now)
|
||||
for w in $(seq 1 $WORKERS); do worker_recv $w & done
|
||||
wait
|
||||
T2=$(ms_now)
|
||||
ELAPSED=$((T2 - T1))
|
||||
|
||||
TOT_RECV=0
|
||||
for w in $(seq 1 $WORKERS); do
|
||||
[ -f "${TMPDIR}/r-${w}.ok" ] && TOT_RECV=$((TOT_RECV + $(cat "${TMPDIR}/r-${w}.ok")))
|
||||
done
|
||||
RPS=$(( TOT_RECV * 1000 / (ELAPSED + 1) ))
|
||||
echo " Recv: ${TOT_RECV}/${TOT} за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)"
|
||||
|
||||
call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QP}" >/dev/null
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 4. Стресс-петля (${STRESS_SEC}s) ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
QX="lq-stress-${TS}"
|
||||
call "Action=CreateQueue&QueueName=${QX}" >/dev/null
|
||||
|
||||
SENT=0; RECV=0; ERRS=0
|
||||
T_END=$(($(date +%s) + STRESS_SEC))
|
||||
|
||||
while [ "$(date +%s)" -lt "$T_END" ]; do
|
||||
R=$(call "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QX}&MessageBody=s-${SENT}")
|
||||
if echo "$R" | grep -q "MessageId"; then SENT=$((SENT + 1)); else ERRS=$((ERRS + 1)); fi
|
||||
|
||||
R=$(call "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QX}&MaxNumberOfMessages=10")
|
||||
C=$(echo "$R" | grep -c "<Message>" || true)
|
||||
RECV=$((RECV + C))
|
||||
done
|
||||
|
||||
echo " Длительность: ${STRESS_SEC}s"
|
||||
echo " Отправлено: ${SENT} ($(( SENT / (STRESS_SEC + 1) )) msg/s)"
|
||||
echo " Получено: ${RECV} ($(( RECV / (STRESS_SEC + 1) )) msg/s)"
|
||||
echo " Ошибки: ${ERRS}"
|
||||
|
||||
call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QX}" >/dev/null
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "╔═══════════════════════════════════════════════════════╗"
|
||||
echo "║ НАГРУЗОЧНЫЙ ТЕСТ ЗАВЕРШЁН ║"
|
||||
echo "║ $(date '+%Y-%m-%d %H:%M:%S') ║"
|
||||
echo "╚═══════════════════════════════════════════════════════╝"
|
||||
|
||||
rm -rf "$TMPDIR"
|
||||
Reference in New Issue
Block a user