Тестирование производительности и k6

Тестирование производительности – это методика тестирования, позволяющая оценить скорость реакции и стабильность работы сервера, сети или приложения под нагрузкой. Этот метод обычно применяют в качестве нагрузочного тестирования. Сегодня все большую важность приобретает время предоставления услуг, которое теперь оценивается как время безотказной работы, а не объем выполненной. Чтобы поддерживать это время стабильным и на высоком уровне, нам необходимо знать свои проблемы с производительностью. Именно здесь на помощь приходит k6.

Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ

Что такое k6? Его преимущества

k6 был выпущен в 2021 году компанией Grafana Labs. Кратко его можно оценить как инструмент, используемый для тестирования производительности и передачи нам результатов этого процесса. K6 создавался с использованием современных технологий, что обеспечило ему ряд преимуществ в определенных областях по сравнению с аналогчными инструментами:

  • Скорость и эффективность
  • Масштабируемость
  • Гибкость сценариев
  • Обширные выходные данные и отчетность

В процессе тестирования производительности, как правило, упускается из виду один момент – роль ресурсов и активности, которые затрачиваются на запросы, поступающие в точку произведения измерений. Одним из существенных преимуществ k6 по сравнению с другими распространенными конкурентами, безусловно, является инфраструктура и язык, на котором он разработан.

Если говорить более конкретно, то JMeter по-прежнему занимает лидирующие позиции в этой методологии, но, к сожалению, ему сложно догнать достаточно новые разработки. В качестве примера можно привести сложность и временные затраты на вмешательство в сценарий с помощью PreProcessors и PostProcessors. Именно здесь на помощь приходит k6. Он делает этот процесс достаточно быстрым и понятным благодаря предоставленному CLI.

Рейтинг активности инструментов тестирования производительности

Концепции k6

В этом инструменте встречаются привычные параметры, которые мы используем во время тестирования производительности и определяем для его работы. Параметры, которые мы будем определять, касаются проведения теста и его результатов. Они задаются в объекте Options:

  • VUs (Virtual Users). Количество пользователей, которые используются/будут использоваться во время тестирования.
  • Итерация. Сколько раз каждый отдельный VU будет повторять один и тот же сценарий.
  • Duration (Продолжительность). Сколько времени будет длиться тест. Значение указывается в миллисекундах (MS).
  • Проверки. Привычные для мира тестов средства утверждения/проверки ответа.
  • Threshold (Порог). Пороговое значение, которое мы будем определять во время тестирования. Если фактическое значение превысит его, тест будет считаться неудачным. Например:
thresholds: { http_req_duration: ['avg<150'] }

Пример k6

В примере с k6 мы будем использовать собственные API. Простейшая форма point-load-теста выглядит следующим образом:

import http from "k6/http";
import { check } from 'k6';

export const options = {
    vus: 1,
    duration : 1000,
    thresholds: { http_req_duration: ['avg<150'] },
    noConnectionReuse: true,
    summaryTrendStats: ['avg','min','max','count']
};
export default function () {
    const url = 'https://test-api.k6.io/public/crocodiles/';
    const header = { headers: {
            'Content-Type': 'application/json',
        },};
    const response = http.get(url,header);
    check(response, {
        'is status 200': (r) => r.status == 200,
    });
}

Чтобы лучше понять структуру k6, давайте разделим ее на две части:

  • Часть, в которой мы задаем поток теста и то, как он будет себя вести, – объект options.
  • Часть, которая будет являться функцией, в которой будет выполняться тест.

Объект Options в его простейшей форме можно представить как конфигурацию.

export const options = {
    vus: 1,
    duration : 100, // in milliseconds
    thresholds: { http_req_duration: ['avg<100'] },
    noConnectionReuse: true,
    summaryTrendStats: ['avg','min','max','count']
};

Для простого тестового сценария будет достаточно приведенного выше объекта options. Среди параметров внутри объекта:

  • Threshold гарантирует, что среднее значение выполненных запросов будет больше или меньше определенного значения.
  • NoConnectionReuse определяет значение keep-alive теста.
  • SummaryTrendStats определяет форматы значений выходных данных, выдаваемых по завершении тестирования.

Теперь под функцией мы можем назвать место, где будет выполняться тест.

const url = 'https://test-api.k6.io/public/crocodiles/';
const header = { headers: {
        'Content-Type': 'application/json',
    },};
const response = http.get(url,header);
check(response, {
    'is status 200': (r) => r.status == 200,
});

В самом простом виде этот шаг выполняется путем добавления заголовка к сделанному нами запросу GET и проверки его статуса.

Структура сценариев и исполнителей в k6

В k6 исполнитель – это компонент, который определяет, как будет направлена нагрузка во время тестирования. Благодаря этому мы можем легко применять различные подходы тестирования производительности. Таким образом мы получаем возможность контролировать распределение реальных пользователей и увеличение нагрузки на приложение.

Как известно, методика, применяемая в качестве эксплуатационных испытаний, подразделяется на несколько подразделов. Кратко:

  • Smoke: низкое значение VUs / 1-5 минут.
  • Load: среднее значение VUs / 10-60 минут.
  • Stress: высокое значение VUs / 1-2 часа.
  • Spike: очень высокое значение VUs / +60 минут.
  • Breakpoint: регулярное увеличение VU / +60 минут.
График зависимости времени тестирования от количества виртуальных пользователей в разных видах тестирования

К некоторых случаях для компаний, находящихся на жизненном цикле, одной конечной точки или простого сценария может быть недостаточно для достижения желаемого результата. Чем более простым и базовым является применяемый сценарий, тем меньше разнообразие и вероятность обнаружения проблем.

Самое большое преимущество, которое мы получаем благодаря k6, – это контроль нагрузки внутри, контролируемое увеличение и уменьшение. Это существенно помогает нам в обнаружении проблем в приложении/системе.

export const options = {
    stages: [
        { duration: '30s', target: 10 }, 
        { duration: '1m', target: 20 },
        { duration: '2m', target: 0 },
    ],
    thresholds: { http_req_duration: ['avg<150'] },
    noConnectionReuse: true,
    summaryTrendStats: ['avg','min','max','count']
};

Согласно приведенным нами значениям, рабочая логика нашего сценария выглядит следующим образом:

  • Общая продолжительность нашего теста составляет 3 минуты 30 секунд.
  • В конце первых 30 секунд внутрь начинает передаваться 10 VUs. Затем в течение 1 минуты начинается увеличение нагрузки внутри с 10 до 20 VUs. По истечении 1 минуты начинается контролируемое уменьшение количества VUs внутри с 20 до 0 в течение 2 минут.
  • Значения длительности фактически определяют темп нарастания и спада нагрузки, которую мы даем внутри.
  • Таким образом, разделив реальную внутреннюю интенсивность на минуты, мы получаем выгоду от сценической составляющей.

Количество запросов в секунду

Другой сценарий, который мы можем создать, – это RPS (Requests per Second). Это тестовая структура, ориентированная на количество запросов в секунду для сценария, который происходит внутри.

export const options = {
    scenarios: {
        my_scenario1: {
            executor: 'constant-arrival-rate',
            duration: '1m', // test duration
            rate: 60, // requests to be made according to the TimeUnit we give
            preAllocatedVUs: 30, // maximum VUs to be used for the given rate value in the test
            timeUnit: '1s', // how long the given rate value will be applied
        },
    }
};

Значение VUs, которое мы указываем, на самом деле не является числом, используемым в начале теста; скорее, в результате примененной скорости тест пытается применяться непрерывно в течение заданного периода времени. Если время отклика увеличивается, продолжает расти и внутреннее значение VUs, чтобы уловить значение скорости, которое мы задаем автоматически.

Стресс-тест

В примере, представленном в этом объекте параметров, мы фактически применяем методологию стресс-тестирования к нашему приложению.

export const options = {
  stages: [
    { duration: '5m', target: 200 }, 
    { duration: '20m', target: 600 }, 
    { duration: '5m', target: 0 }, 
  ],
};

Тестирование точек останова

export const options = {
  executor: 'ramping-arrival-rate', // parameter to control the load to the application
  stages: [
    { duration: '40m', target: 4000 }, // the number of VUs to be reached at the end of the specified duration
  ],
};

Наблюдение за результатами метрики k6

Вместо того чтобы отслеживать и интерпретировать метрики, полученные в ходе тестирования, в текстовом виде, можно визуализировать их на локальной машине. Это позволяет считывать данные приложения в режиме реального времени, что помогает более оперативно выявлять потенциальные проблемы в ходе тестирования.

Мы можем легко создавать наши собственные панели метрик, выгружая выходные показатели k6 по умолчанию на панели мониторинга с помощью Grafana и Influx.

В нашем примере мы будем работать с Docker локально. Давайте настроим Influx на Docker.

Создадим сетевой мост для Docker:

$ docker network create --driver bridge influxdb-telegraf-net

Run Influx на Docker

docker run -d --name=influxdb \
 -p 8086:8086 \
 -v  /tmp/testdata/influx:/root/.influxdb2 \
 --net=influxdb-telegraf-net \
 influxdb:2.0

Теперь Influx готов к работе на локальном хосте: 8086. При первом посещении этого адреса будет запрошена информация о хранилище и пользователе. Заполните их, чтобы завершить этот шаг.

Расширение k6 InfluxDB

Когда мы устанавливаем k6, он поставляется с поддержкой InfluxDB v1 по умолчанию. Однако в данном примере мы используем InfluxDB v2, поэтому применим расширение.

xk6 build - with github.com/grafana/xk6-output-influxdb

В результате будет создан двоичный файл, обеспечивающий поддержку InfluxDB v2. Далее мы запустим наши тесты с этим двоичным файлом.

Для этого мы можем использовать команду test start.

K6_INFLUXDB_ORGANIZATION=${organizationName} K6_INFLUXDB_BUCKET=${bucketName} K6_INFLUXDB_TOKEN=${TOKEN} ./k6 run -o xk6-influxdb=http://localhost:8086 ./testScript.js

Тесты, запущенные с этой переменной окружения, будут экспортированы в InfluxDB.

Grafana на Docker

С помощью этой команды вы можете запустить экземпляр Grafana по адресу localhost:3000.

docker run -d -p 3000:3000 --name=grafana grafana/grafana-enterprise

Теперь Influx работает на localhost:8086, а Grafana – на localhost:3000.

Давайте добавим источник данных Influx в Grafana.

Добавление источника данных Influx в Grafana

После выполнения этих шагов мы сможем запросить Influx из Grafana.

Давайте создадим панель мониторинга. Для этого мы можем использовать данный шаблон. С его помощью мы можем увидеть основные метрики k6.

Создание панели мониторинга с использованием шаблона, с помощью которого можно увидеть основные метрики k6

Теперь наши тесты k6 можно наблюдать через Grafana.

В заключение следует отметить, что тестирование производительности – это важнейшая методология тестирования, позволяющая оценить реакцию системы под нагрузкой и ее стабильность. k6 является мощным и эффективным инструментом для таких тестов. Его преимущества, такие как скорость, масштабируемость, гибкие сценарии, обширные выходные данные и отчетность, – лишь некоторые из важных факторов выбора k6. Благодаря этим преимуществам пользователи могут лучше понять и повысить производительность и стабильность своих приложений.

Рассмотренные нами фундаментальные концепции, установка, использование и различные структуры сценариев k6 являются большим подспорьем для эффективного проведения тестов производительности. Эти возможности обеспечивают успешное завершение тестирования и повышают устойчивость приложения. Помните, что правильное и эффективное тестирование производительности – это залог успеха приложения и удовлетворенности пользователей.

Перевод статьи «Performance Testing and k6».

1 комментарий к “Тестирование производительности и k6”

  1. Пингбэк: Автоматизация тестирования производительности с K6

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *