perf: optimize authorization scoreline and workers

This commit is contained in:
2026-07-30 09:12:27 +08:00
parent 4bea745b79
commit bedc77bffd
52 changed files with 21911 additions and 347 deletions

View File

@@ -0,0 +1,12 @@
# TIKU API performance scenarios
Run the API against a prepared PostgreSQL database, then execute:
```bash
TIKU_BASE_URL=http://localhost:5000 \
TIKU_TENANT_CODE=<tenant-code> \
TIKU_ACCESS_TOKEN=<optional-access-token> \
k6 run tools/performance/tiku-api.js
```
Do not store access tokens or database credentials in this directory. The default threshold is only a smoke gate; release comparison uses the same dataset and environment before and after a change, and requires at least a 50% p95 improvement for the targeted endpoint.

View File

@@ -0,0 +1,59 @@
import http from 'k6/http';
import { check, sleep } from 'k6';
const baseUrl = __ENV.TIKU_BASE_URL || 'http://localhost:5000';
const tenantCode = __ENV.TIKU_TENANT_CODE || '';
const accessToken = __ENV.TIKU_ACCESS_TOKEN || '';
export const options = {
scenarios: {
public_catalog: {
executor: 'constant-vus',
vus: Number(__ENV.TIKU_PUBLIC_VUS || 10),
duration: __ENV.TIKU_DURATION || '30s',
exec: 'publicCatalog',
},
scoreline_page: {
executor: 'constant-vus',
vus: Number(__ENV.TIKU_SCORELINE_VUS || 10),
duration: __ENV.TIKU_DURATION || '30s',
exec: 'scorelinePage',
},
tenant_bootstrap: {
executor: 'constant-vus',
vus: Number(__ENV.TIKU_BACKOFFICE_VUS || 5),
duration: __ENV.TIKU_DURATION || '30s',
exec: 'tenantBootstrap',
startTime: '1s',
},
},
thresholds: {
http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<1000'],
},
};
function tenantParams(authenticated = false) {
const headers = tenantCode ? { 'x-tenant-code': tenantCode } : {};
if (authenticated && accessToken) headers.Authorization = `Bearer ${accessToken}`;
return { headers };
}
export function publicCatalog() {
const response = http.get(`${baseUrl}/api/catalog/regions`, tenantParams());
check(response, { 'catalog is 200': (result) => result.status === 200 });
sleep(0.1);
}
export function scorelinePage() {
const response = http.get(`${baseUrl}/api/scoreline/records?page=1&pageSize=20`, tenantParams());
check(response, { 'scoreline is 200': (result) => result.status === 200 });
sleep(0.1);
}
export function tenantBootstrap() {
if (!accessToken) return;
const response = http.get(`${baseUrl}/api/tenant-backoffice/ui-bootstrap`, tenantParams(true));
check(response, { 'bootstrap is 200': (result) => result.status === 200 });
sleep(0.1);
}