Perfscale news #6. GraphQL, поддержка Import, и метрики
Об авторе, кто он такой и что делает можно почитать тут. Пост специально открыт для всех, чтобы не было проблем с разным уровнем доступа.
Приветствую, любители нагрузки. Для истории прошлые выпуски:
- Новости Perfscale № 1
- Perfscale news #2: Fix Protocol, Magic metrics и MCP
- perfscale news #3 Websocket, Inference, NPM
- Perfscale news #4. GRPC, Fixed Triggers, Child Process
- Perfscale news #5. SQL, thresholds и оптимизации
Во-первых, хочется поблагодарить пользователя Aleksandr Lebedev (TG: @iamtechnomage) за приятного маскота! [Ссылка на первое упоминание маскота].

Во-вторых в этой ревизии будет довольно мало новостей, касательно Perfscale Platform. Из-за того, что я до сих пор борюсь с Linked Accounts.
И по традиции мы начинаем с
Perfscale OSS (open source software)
Теперь версии 0.10.0. Github release.
GraphQL
Да, теперь вы можете нагружать ваши GraphQL сервисы. Появился шаг std/graphql@v1. Выглядит это следующим образом
steps:
- name: fetch viewer
use: std/graphql@v1
with:
url: 127.0.0.1:4000/graphql
query: |
query GetViewer($id: ID) {
viewer(id: $id) { id name }
}
variables: { "id": "u-1" }
check:
status: 200
duration_ms_lt: 250
outputs: viewer
- name: list widgets
use: std/graphql@v1
with:
url: 127.0.0.1:4000/graphql
query: |
{
widgets { id name }
}
outputs: widgets
- name: rename widget
use: std/graphql@v1
with:
url: 127.0.0.1:4000/graphql
query: |
mutation Rename($id: String!, $name: String!) {
renameWidget(id: $id, name: $name) { id name }
}
# ${uuid} expands per execution — every rename sends a fresh name.
variables: { "id": "w-1", "name": "renamed-${uuid}" }
check:
status: 200
Ну а конфигурация у вас достаточно простая.
vus: 5 duration: 30s
Кстати из приятного бонуса: команда lint также валидирует тест и сами GraphQL схемы за вас!
Не забыл и по поводу метрик: вывод самого просто теста такой:
vus....................: 5 min=1 max=5 iterations..............: 210 7.00/s graphql_errors: 0 0.00/s graphql_req_failed: 0 0.00/s graphql_req_duration: avg=3.10ms p(50)=2.90ms p(90)=4.20ms p(95)=4.80ms p(99)=6.10ms min=1.80ms max=9.40ms count=630 graphql_op_GetViewer_duration: avg=2.95ms p(50)=2.80ms p(90)=4.00ms p(95)=4.60ms p(99)=5.90ms min=1.80ms max=8.70ms count=210 graphql_op_Rename_duration: avg=3.35ms p(50)=3.10ms p(90)=4.50ms p(95)=5.10ms p(99)=6.60ms min=2.00ms max=9.40ms count=210 http_req_duration: avg=3.10ms p(50)=2.90ms p(90)=4.20ms p(95)=4.80ms p(99)=6.10ms min=1.80ms max=9.40ms count=630 http_reqs: 630 21.00/s
Ну а метрики пишутся следующие graphql_errors, graphql_req_failed, graphql_req_duration и по каждой операции. Поскольку GraphQL вызывается поверх HTTP, то и HTTP метрики никто не отменял: http_req_duration, http_reqs.
А еще, в рамках GraphQL сделал introspection. Это когда перед тестом, один раз у нас вызывается получение GraphQL схемы.
Пример с выключеным introspection
steps:
- name: fetch viewer
use: std/graphql@v1
with:
url: api.example.com/graphql
introspection: false # не фетчить схему вообще
query: |
{ viewer { id } }
По умолчанию introspection: true. А если у вас лежат GraphQL локально, то можно импортнуть схему через опцию в шаге schema_file: schema.graphql. Но помните, если у вас локальный schema.graphql фаил, то это требует allow_file_actions: true для вашего configuration.yaml
Import
Когда нагрузочные конфиги живут в десятке репозиториев, vus, duration и пороги копипастятся — и расползаются по копипасте. Теперь и test.yaml, и config.yaml умеют наследоваться от общей базы:
# раз — raw URL, ref зашит в путь import: "raw.githubusercontent.com/org/repo/v1.2.0/perf/_base.yaml" # два — любой git-хост, включая self-hosted по SSH import: git: git@gitlab.example.com:group/repo.git ref: v1.2.0 file: perf/_base.yaml
Я понимаю, что тут есть проблема с кешированием. Поэтому для запуска теста, где у нас обновился конфиг можно вызвать с ключем --refresh-imports. Следующий вопрос, который можно поднять: а что насчет supply chain атак: ведь можно импортнуть зловред. Поэтому есть настройка, --allow-remote-import, которая разрешает импортировать удаленные конфигурации.
Ну и в целом пару слов про политики запусков, когда и где применять. Посмотрим на конфиг
# config.yaml allow_file_actions: true # шаги std/file-read@v1 / file-write, multipart file allow_process_actions: true # std/child_process@v1 / kill_process
allow_file_actions — позволяет выполнять шаги для std/file-read@v1 / file-write
allow_process_actions — позволяет выполнять шаги std/child_process@v1 / kill_process. Полезно, если у вас есть sidecar. В нашем случае — это веб сервер
Perfscale Platform
Тут изменений не много. Добавилась поддержка GraphQL и import. Пока не самым красивым образом отображается import. Так что эта фича в процессе, как и linked accounts.
А на сегодня все. Нагружайте сервисы с душой, а метрики смотрите безпристрасно!