Руководства8 июля 2026 г. · 4 мин чтения

Perfscale теперь говорит на HTTP QUERY — по всему стеку

Метод QUERY (безопасный, кэшируемый, с телом запроса) появился в perfscale CLI, агенте perfscaled и controlplane. Что это такое и как его нагружать.

Автор: Команда Perfscale

Perfscale теперь говорит на HTTP QUERY — по всему стеку

Поисковые и фильтрующие эндпоинты десятилетиями жили в неудобном углу HTTP. GET семантически правильный — безопасный, идемпотентный, кэшируемый — но упаковка сложного фильтра в query-string упирается в лимиты длины, боль с кодированием и логи, полные чувствительных параметров. Поэтому все берут POST — и взамен отдают безопасность и кэширование.

Ответ IETF — метод QUERY: безопасный, как GET, но с телом запроса, как у POST. Поисковые API в стиле Elasticsearch, фильтрующие эндпоинты рядом с GraphQL, отчётные запросы — это метод, которого они ждали.

По мере того как фреймворки и шлюзы выкатывают поддержку, эти эндпоинты понадобится нагружать, как и любые другие. Поэтому QUERY теперь работает во всём стеке perfscale — рядом с GET, POST, PUT и остальными.

В perfscale CLI (нативный движок)

Нативный YAML-движок пропускает любой валидный токен метода как есть, вместе с телом:

steps:
  - name: поиск по товарам
    use: std/http@v1
    with:
      method: QUERY
      url: https://api.example.com/products/search
      body:
        category: "electronics"
        price_max: 500
    check:
      status: 200

Запуск обычный:

perfscale run -f search.test.yaml -c load.yaml

Перцентили латентности, RPS и доля ошибок попадают в тот же summary http_req_*, что и у любого другого метода — дашбордам и пайплайну --report всё равно, что метод нестандартный.

В k6-скриптах

У модуля http в k6 нет шортката http.query(), но http.request() принимает метод первым аргументом:

import http from 'k6/http';

export default function () {
  http.request('QUERY', 'https://api.example.com/products/search',
    JSON.stringify({ category: 'electronics', price_max: 500 }),
    { headers: { 'Content-Type': 'application/json' } });
}

Это работает и с чистым k6, и через perfscale run --k6. Редактор тестов в controlplane теперь тоже разбирает вызовы http.request(), так что QUERY-шаг появляется в превью нативных шагов наравне с шорткатами.

В агенте perfscaled

Эндпоинт нативных шагов агента принимает те же определения по HTTP, так что оркестрируемые флоты получают QUERY бесплатно:

POST /api/v1/run/steps
{
  "steps": [
    { "name": "search",
      "use": "std/http@v1",
      "with": { "method": "QUERY",
                "url": "https://api.example.com/products/search",
                "body": { "category": "electronics" } },
      "check": { "status": 200 } }
  ],
  "config": { "vus": 50, "duration": "5m" },
  "mode": "stream"
}

Почему это важно для нагрузочного тестирования

QUERY меняет профиль производительности поисковых эндпоинтов — и лучше измерить это до того, как это сделает продакшн:

  • В игру вступает кэширование. Ответы QUERY кэшируемы; нагрузочный тест, игнорирующий поведение кэша, переоценит нагрузку на origin.
  • Тело у безопасного метода проходит через прокси, шлюзы и WAF, которые так никогда не работали. Некоторые под нагрузкой поведут себя странно — лучше узнать об этом во вторник днём на стейджинге.
  • Серверные фреймворки маршрутизируют QUERY через generic-обработчики, пока не появится первоклассная поддержка, — а это зачастую другие цепочки middleware и другая латентность, чем у GET.

Направьте QUERY-сценарий на свой staging-шлюз, прогоните свип по VUs и сравните перцентили с эквивалентным POST. Если цифры разойдутся — вы знаете, куда смотреть.

Всё описанное уже в текущем main perfscale — без флагов и конфигурации. Просто напишите method: QUERY.