Цели производительности GrantForge рассчитаны на крупную организацию: миллион учётных записей, десять тысяч ролей, сто тысяч ресурсов. Системный бенчмарк запускается ежесуточно на PostgreSQL 17, и сборка завершается ошибкой, если какой-либо показатель превышает свой предел.
Цели
| Метрика | Смысл | Предел |
|---|---|---|
authz.snapshot.hit |
Кэшированный снимок авторизации (используется при каждом вызове API) | p99 1 ms |
authz.snapshot.build |
Первичное вычисление снимка консоли для учётной записи | p95 50 ms |
authz.snapshot.app |
Вычисление снимка в приложении с большим деревом ресурсов | p95 50 ms |
api.users.page |
Одна страница списка пользователей (в пределах первых 500 страниц) | p95 200 ms |
api.users.search |
Поиск пользователей по имени | p95 200 ms |
api.groups.page |
Одна страница списка групп пользователей | p95 200 ms |
api.roles.list |
Список ролей (без постраничной разбивки) | p95 200 ms |
api.me.authorization |
Права текущей учётной записи | p95 200 ms |
api.member.groups |
Учётная запись с правом одной страницы, обращающаяся к защищённому списку | p95 200 ms |
jmh.derivation.* |
Подготовка вывода для большого дерева ресурсов; вывод двадцати выдач (JMH) | avg 50 / 5 ms |
Пределы можно только ужесточать; любое их ослабление требует задокументированного решения.
Данные
Бенчмарк запускает настоящий сервер, завершает инициализацию, а затем записывает данные через собственные сущности приложения:
- 100 подразделений, одна группа пользователей на тысячу учётных записей, 100 должностей;
- Каждая учётная запись принадлежит одному подразделению и одной группе пользователей; одна учётная запись из десяти занимает должность, а одна из двадцати имеет роли, назначенные напрямую;
- Каждая десятая роль наследует одну из первых ста ролей; каждая группа пользователей получает три роли, каждое подразделение — две, каждая должность — одной роли; каждой роли выдаётся пять страниц консоли;
- Одно приложение: сто страниц под несколькими модулями, девять операций на страницу; каждая десятая роль получает двадцать из этих страниц и операций.
Каждая метрика прогревается, а затем измеряется вызов за вызовом.
Запуск локально
bash script/ci/perf_benchmark.sh full # 目标规模,postgres:17(需要 Docker),检查上限
bash script/ci/perf_benchmark.sh smoke # H2 上的小规模,只确认基准能运行
bash script/ci/perf_benchmark.sh full mysql:8.4 # 其他数据库Отчёт записывается в perf/target/perf-report.json, а таблица дополнительно печатается в лог. Дополнительные опции можно передать через PERF_OPTS:
| Опция | По умолчанию | Назначение |
|---|---|---|
perf.database |
postgres:17 |
h2 или <engine>:<version> |
perf.users / perf.roles / perf.resources |
1000000 / 10000 / 100000 | Объём данных |
perf.samples / perf.warmup |
1000 / 200 | Измерения и итерации прогрева на каждую метрику |
perf.jmh |
true |
Дополнительно запускать бенчмарки JMH |
perf.enforce |
true |
Завершать процесс со статусом 1 при превышении предела |
Почему это быстро
- Снимки авторизации кэшируются для каждой учётной записи и полностью инвалидируются по версиям каталога и тенанта; попадание в кэш — это одно чтение из памяти.
- Вывод выполняется в памяти: дерево ресурсов, отношения наследования и назначения предзагружаются в компактные структуры, что позволяет избежать запросов к каждому элементу.
- Списковые конечные точки всегда разбиты на страницы, а сортировка и фильтрация выполняются по индексированным столбцам; ленивые ассоциации загружаются пакетами по 64, а записи фиксируются пакетами по 50 (идентификаторы генерируются приложением, поэтому пакетная вставка возможна).
