こんにちは。よっしーです(^^)
今日は、APIの負荷テストについてご紹介します。
背景
Dockerで構築したWebアプリの開発環境において、k6を利用した負荷テストについて調査したときの内容を備忘として残しました。
開発環境のソースは下記のリポジトリにあります。
機能の検証
通常、パフォーマンステストでは次の点に最も注意が払われます:
- レイテンシ(遅延):システムがどれだけ速く応答するか
- 可用性:システムがどれだけ頻繁にエラーを返すか
http_req_durationメトリックはレイテンシを報告し、http_req_failedはHTTPリクエストのエラーレートを報告します。前のテスト実行からは、次の結果が提供されました:
http_req_duration..............: avg=106.14ms min=102.54ms med=104.66ms max=198.93ms p(90)=113.78ms p(95)=114.58ms
{ expected_response:true }...: avg=106.14ms min=102.54ms med=104.66ms max=198.93ms p(90)=113.78ms p(95)=114.58ms
http_req_failed................: 0.00% ✓ 0 ✗ 1501
テストの解析は、デフォルトのメトリックで利用可能なものを超える場合があります。より有意義な結果分析のために、機能を検証しエラーを報告することも考えられます。
アプリケーションの障害の一部は、高トラフィックなど特定の負荷条件下でのみ発生する場合があります。これらのエラーは見つけるのが難しいです。失敗の原因をより速く見つけるために、APIをインストゥルメンテーションし、リクエストが予想される応答を受け取るかどうかを検証します。k6では、アプリケーションロジックを検証するためにChecksを使用できます。
Checksはテスト実行中に条件を検証します。たとえば、Checksを使用してAPIの応答を検証および追跡することができます。Checksを使用すると、HTTPステータスや返されるデータなど、予想されるAPIの応答を確認できます。
下記のスクリプトは現在、HTTP応答のステータス、ヘッダー、およびペイロードを検証しています。
import { check } from 'k6';
import http from 'k6/http';
export const options = {
scenarios: {
my_scenario1: {
executor: 'constant-arrival-rate',
duration: '30s', // total duration
preAllocatedVUs: 50, // to allocate runtime resources
rate: 50, // number of constant iterations given `timeUnit`
timeUnit: '1s',
},
},
};
export default function () {
const payload = JSON.stringify({
name: 'lorem',
surname: 'ipsum',
});
const headers = { 'Content-Type': 'application/json' };
const res = http.post('https://httpbin.test.k6.io/post', payload, { headers });
check(res, {
'Post status is 200': (r) => res.status === 200,
'Post Content-Type header': (r) => res.headers['Content-Type'] === 'application/json',
'Post response name': (r) => res.status === 200 && res.json().json.name === 'lorem',
});
}
このスニペットでは、すべてのチェックが成功しました。
my_scenario1 ✓ [======================================] 00/50 VUs 30s 50.00 iters/s
✓ Post status is 200
✓ Post Content-Type header
✓ Post response name
負荷が 1 秒あたり 300 リクエストに増加した後、結果は 8811 件の成功リクエストと 7 件の失敗リクエストを返しました。
my_scenario1 ✓ [======================================] 000/300 VUs 30s 300.00 iters/s
✗ Post status is 200
↳ 99% — ✓ 8811 / ✗ 7
✗ Post Content-Type header
↳ 99% — ✓ 8811 / ✗ 7
✗ Post response name
↳ 99% — ✓ 8811 / ✗ 7
デフォルトでは、失敗したチェックはテストを失敗させたり中止させたりしません。この点で、チェックは他の種類のテストのアサーションとは異なります。負荷テストは、数千または数百万のスクリプトイテレーションを実行し、各イテレーションには数十のアサーションが含まれることがあります。
一定の失敗率は許容されることがあり、それはSLO(Service Level Objective、サービスレベル目標)の「n個の9」または組織のエラーバジェットによって決定されます。
おわりに
今日は、APIの負荷テストについてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント