Реалізація стрес-тестування для визначення меж навантаження сайту

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація стрес-тестування для визначення меж навантаження сайту
Складна
~3-5 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1224
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    859
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1069
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    829
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    831

Стрес-тестування: визначення меж навантаження

Стрес-тест навмисно перевантажує систему за межами нормальної експлуатації для знаходження точки відмови. Відповідь на запитання: при якому RPS починають зростати помилки? Як система відновлюється після перевантаження? Де вузьке місце — БД, CPU, пам'ять, мережа?

Методологія

Крок 1: Визначити baseline. Запустити нормальне навантаження (50–70% від очікуваного піку) та зафіксувати метрики: p95 latency, error rate, CPU/memory.

Крок 2: Поступове збільшення. Підвищити навантаження кроками по 10–20% кожні 2–5 хвилин. Зафіксувати точку, де починають зростати помилки або latency.

Крок 3: Знайти breaking point. Продовжити до деградації (error rate > 5% або latency > 5x baseline).

Крок 4: Відновлення. Зняти навантаження та спостерігати, як швидко система повертається в норму.

k6 сценарій стрес-тесту

// tests/stress/breaking-point.js
import http from 'k6/http'
import { check, sleep } from 'k6'
import { Rate, Trend, Counter } from 'k6/metrics'

const errorRate = new Rate('errors')
const requestsPerSecond = new Counter('requests_per_second')

export const options = {
  stages: [
    // Розігрів до нормального трафіку
    { duration: '2m',  target: 50 },
    { duration: '3m',  target: 50 },   // базовий рівень

    // Поступове нарастання
    { duration: '2m',  target: 100 },
    { duration: '3m',  target: 100 },

    { duration: '2m',  target: 200 },
    { duration: '3m',  target: 200 },

    { duration: '2m',  target: 400 },
    { duration: '3m',  target: 400 },

    { duration: '2m',  target: 800 },
    { duration: '3m',  target: 800 },

    { duration: '2m',  target: 1600 },
    { duration: '3m',  target: 1600 },

    // Охолодження та спостереження за відновленням
    { duration: '5m',  target: 50 },
    { duration: '3m',  target: 0 },
  ],

  // Не переривати тест при перевищенні порогів — потрібно бачити повну картину
  thresholds: {
    http_req_duration: [
      { threshold: 'p(95)<2000', abortOnFail: false },
    ],
    errors: [
      { threshold: 'rate<0.1', abortOnFail: false }
    ]
  }
}

const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000'

export default function() {
  const responses = http.batch([
    ['GET', `${BASE_URL}/api/products?limit=20`],
    ['GET', `${BASE_URL}/api/categories`],
  ])

  responses.forEach(r => {
    check(r, { 'status 2xx': (r) => r.status >= 200 && r.status < 300 })
    errorRate.add(r.status >= 400)
  })

  requestsPerSecond.add(2)
  sleep(0.1)
}

export function handleSummary(data) {
  // Знайти точку деградації з зібраних даних
  const stages = analyzeStages(data)
  return {
    'stress-results.json': JSON.stringify(data, null, 2),
    stdout: generateReport(stages)
  }
}

function generateReport(stages) {
  return `
=== STRESS TEST REPORT ===
Breaking Point Analysis:
${stages.map(s => `  VUs: ${s.vus} | p95: ${s.p95}ms | Errors: ${(s.errorRate*100).toFixed(1)}%`).join('\n')}
`
}

Моніторинг під час тесту

Запустити паралельно збір системних метрик:

#!/bin/bash
# scripts/monitor-stress-test.sh

TARGET_HOST="app-server-ip"
INTERVAL=10  # секунди

while true; do
  TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)

  # CPU, Memory, Load Average
  ssh $TARGET_HOST "
    echo -n '$TIMESTAMP '
    echo -n 'cpu:'; top -bn1 | grep 'Cpu(s)' | awk '{print \$2}'; echo -n ' '
    echo -n 'mem:'; free | grep Mem | awk '{print \$3/\$2 * 100}'; echo -n ' '
    echo -n 'load:'; cat /proc/loadavg | awk '{print \$1}'
    echo -n 'conns:'; ss -s | grep -o 'estab [0-9]*' | awk '{print \$2}'
  "

  # PostgreSQL: активні запити та блокування
  ssh $TARGET_HOST "
    PGPASSWORD=pass psql -U app -d appdb -t -c \"
      SELECT 'active_queries:', count(*) FROM pg_stat_activity
        WHERE state = 'active' AND query NOT LIKE '%pg_stat%';
      SELECT 'long_queries:', count(*) FROM pg_stat_activity
        WHERE state = 'active' AND query_start < NOW() - interval '5 seconds';
      SELECT 'locks:', count(*) FROM pg_locks WHERE NOT granted;
    \"
  "

  sleep $INTERVAL
done | tee stress-monitor.log

Аналіз результатів з Prometheus + Grafana

# k6 з Prometheus Remote Write
k6 run \
  -o experimental-prometheus-rw \
  --env K6_PROMETHEUS_RW_SERVER_URL=http://prometheus:9090/api/v1/write \
  --env K6_PROMETHEUS_RW_TREND_AS_NATIVE_HISTOGRAM=true \
  tests/stress/breaking-point.js
# Запити в Grafana для аналізу стрес-тесту

# RPS у реальному часі
rate(k6_http_reqs_total[30s])

# Error rate по часу (знайти момент деградації)
rate(k6_http_req_failed_total[30s]) / rate(k6_http_reqs_total[30s])

# p95 latency у реальному часі
histogram_quantile(0.95, rate(k6_http_req_duration_seconds_bucket[30s]))

# Кореляція: навантаження vs latency vs помилки

Визначення вузького місця

# analyze_stress_results.py
import json
import pandas as pd

def analyze_breaking_point(results_file):
    with open(results_file) as f:
        data = json.load(f)

    # Витягти часові ряди
    metrics = data['metrics']

    analysis = {
        'max_rps_before_errors': find_max_sustainable_rps(metrics),
        'error_threshold_rps': find_error_threshold(metrics),
        'latency_degradation_point': find_latency_degradation(metrics),
        'recovery_time_seconds': find_recovery_time(metrics),
    }

    print("=== Breaking Point Analysis ===")
    print(f"Max sustainable RPS (< 1% errors): {analysis['max_rps_before_errors']}")
    print(f"Error threshold RPS: {analysis['error_threshold_rps']}")
    print(f"p95 > 1s at RPS: {analysis['latency_degradation_point']}")
    print(f"Recovery time after load removal: {analysis['recovery_time_seconds']}s")

    # Рекомендації
    if analysis['max_rps_before_errors'] < 100:
        print("\n[!] LOW capacity. Consider: DB connection pooling, caching, horizontal scaling")
    elif analysis['recovery_time_seconds'] > 120:
        print("\n[!] SLOW recovery. Consider: circuit breakers, graceful degradation")

    return analysis

Типові вузькі місця та діагностика

Симптом Ймовірна причина Діагностика
Latency зростає, CPU низька Блокування БД або повільні запити pg_stat_activity, slow query log
CPU 100%, мало помилок Обчислювальний bottleneck top, application profiler
ENOMEM помилки Витік пам'яті або OOM free -m, /proc/meminfo
Connection refused Connection pool вичерпаний pgBouncer stats, netstat
502 Bad Gateway Worker processes перевантажені Nginx error log, worker_processes

Часовий графік

Стрес-тест з поступовим профілем навантаження, моніторингом та аналізом breaking point — 2–3 робочих дні.