Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
PHP で負荷試験のシナリオを書きたい!ので amphp を使って自作した件
Search
Masaru Yamagishi
September 16, 2023
Programming
1.3k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHP で負荷試験のシナリオを書きたい!ので amphp を使って自作した件
PHP カンファレンス沖縄 2023 登壇資料です。
Masaru Yamagishi
September 16, 2023
More Decks by Masaru Yamagishi
See All by Masaru Yamagishi
Babylon.js 勉強会 vol.4 JAPAN 活動紹介
myamagishi
0
190
PSR-15 はあなたのための ものではない? - phpcon2024
myamagishi
0
1.2k
3D ブラウザゲーム開発を始めたい人のために準備している話
myamagishi
1
260
「DI」と仲良くなる
myamagishi
6
3.8k
大解剖!amphpを使って非同期 PHP を実現しよう!
myamagishi
1
4.3k
秒間 10,000 リクエストを "簡単に"いなすゲームサーバーを Laravel で作る設計
myamagishi
19
17k
xR グラスが普及した新時代を妄想する - XRKaigi 2022
myamagishi
0
320
Reflection を使いこなして、 オブジェクトを型安全に マッピングしよう!
myamagishi
2
1k
世界最速? で PHP8 Native Framework 作った
myamagishi
1
880
Other Decks in Programming
See All in Programming
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
280
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
120
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.4k
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
620
AI時代のFlutter品質設計 — アプリ品質を守るQuality Layers
omatty198
0
360
Crash Auto Pipelines
veronikapj
1
380
flutter_test のその先へ — Flutter アプリの LLM 機能に「評価」という品質保証を
kosukesaigusa
0
200
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.7k
そのデザイントークン、Flutterでも同じ見た目になりますか?
nakamizu
0
310
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
180
Inertia Rails: The One-Person Framework with React & Friends
skryukov
0
380
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
220
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
699
190k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
350
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
121
120k
The Pragmatic Product Professional
lauravandoore
37
7.5k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.3k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
WENDY [Excerpt]
tessaabrams
14
40k
It's Worth the Effort
3n
188
29k
Accessibility Awareness
sabderemane
1
290
From π to Pie charts
rasagy
1
440
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
830
Transcript
PHP で負荷試験のシナリオを書きたい!の で amphp を使って自作した件 2023/09/16 PHP カンファレンス沖縄 やまゆ
セッション概要 jMeter, Locust, k6, ... 負荷試験ツールは色々ありますが、どれも PHP でシナリオを書くことができません。 PHP のコードは
PHP でシナリオ も書いてしまった方が一貫性があって良いですよね? PHP 8.1 から Fiber が入ったことで、 PHP でも非同期・並行的な処理が簡単に実装 出来るようになりました。 PHP によるシナリオツール、 ないなら作ろう精神 で、自作することにしました。 Fiber ままで並行処理を作るのは大変なので、今回は amphp を使って簡単に distributed なシステムを構築します。 今回は何故自作したのか、どのように並行処理を実装したのかを紹介します。 ターゲット 負荷試験したい方 PHP で並行処理ってどうやるの?という方
赤魔道士系エンジニア ㈱インフィニットループ at 札幌/仙台 やまゆ この画像は自撮りでも いつも使っているアイコンでも構いません ☕
負荷試験
負荷試験 大規模 Web サービスのリリース・大規模アプデに欠かせない事前テスト 想定された Monthly Active User(MAU) から仮定する Request
per sec(rps) が安定 して稼働するか、負荷をかけ続けて試験すること ↓やらないとどうなる? - 事前スケーリングのサイズが決まらない - リリース時に🔥炎上🔥する
負荷試験内容 1. MAU 定義 2. シナリオ定義 3. rps 定義 4.
負荷シナリオプログラム作成 5. 実施・監視・適宜最適化 6. レポート
負荷試験定義例 - 事前のアンケートや類似事例から MAU を検討 - 想定されたシナリオをいくつか作成 - トップページ ->
リンク回遊 -> ユーザー登録 -> プロフィール編集 -> リンク回遊 - トップページ -> ユーザー登録 -> 課金 -> リンク回遊 - ソシャゲ: ユーザー登録 -> ログイン -> チュートリアル -> コアサイクル - シナリオから「何秒おきにどんな API 順で呼ばれるか」表を作成 - 同時に、シナリオ表をプログラム化(機械的に呼べるようにする) - MAUとシナリオ表から「1秒間に何リクエスト送られるか」を推測
負荷試験定義例: rps - 仮に 20 万 MAU とする - 仮定として、全体の
50 %(10万) が最大の同時接続数とする - シナリオ表から、平均的な rps が 0.2 であるとする - 100,000 * 0.2 = 20,000 rps - このサービスに安定・継続して耐えるべき値は 20,000 rps と仮定
Next action? 20,000 rps を耐えられる構成を考える そもそも 20,000 rps がどのリソースにどれくらいの負荷を掛けるのか、計測する必要 がある
ということで機械的に計測するための負荷試験ツールの出番!
負荷をかける (HTTP リクエストする) ツール
Apache jMeter https://jmeter.apache.org/
Locust https://locust.io/
Locust Scenario(Python)
k6 https://k6.io/
k6 Scenario(JavaScript like)
PHP なくない?
じゃあ作るか
heavyrain
heavyrain - PHP Loadtest/Stresstest tool
heavyrain - PHP Loadtest/Stresstest tool
Why? - Locust 使っていたが python かぁ...となる - k6 もなんか変な JavaScript
だしなぁ...となる - jMeter…となる - PHP でシナリオ書けるのが一番楽やろ - 今は PHP でも Fiber 等で並行処理強くなってきたし - 自分が一番欲しい(普通にプロジェクトの負荷試験に使いたい) - ないなら作ろう精神
同期的だと無理
同期処理シーケンス
非同期処理シーケンス
非同期処理における並行 & 並列 非同期処理には種類がある - 並行(Concurrency) - 並列(Parallelism) 言語の仕組みによって並行性が高かったり並列性が高かったりする 言語だけでなくドキュメントでもこの表現は揺れているので、今回の資料では
- 並行=シングルスレッドでうまいこと非同期する - 並列=マルチスレッド・マルチプロセスで非同期する とする。
PHP は(基本的に)シングルスレッド なので「並列」ではなく「並行」が近い マルチプロセスは可能だが、プロセス間通信はちょっと大変 マルチスレッドは extension を使えば可能(zts じゃないとダメ)
JavaScript も(基本的に)シングルスレッド
Fiber
Fiber https://www.php.net/manual/ja/language.fibers.php サードパーティ extension なしで「非同期・並行処理」を実現できる API PHP 8.1 から利用可能 シンプルで低レベルの
API を提供している
None
シンプルすぎて わからん 🤔
Revolt
Revolt イベントループを管理してくれる低レベル API ライブラリ - Defer: go の defer みたいに、イテレーションの最後に
- Delay: x 秒後に - Repeat: x 秒おきに - Stream readable: ストリームが読み込めるようになったら - Stream writable: ストリームに書きこめるようになったら - Signal: プロセスシグナルを OS から受け取ったら
None
シンプルすぎて わからん 🤔
amphp
amphp Revolt をベースとした高レベル非同期 API を提供するライブラリ群 File, Log, MySQL, Redis などの
I/O 処理を非同期化し ブロックしない形で実行出来るライブラリがある HTTP Server を動かすこともできる
None
async await
async? 「将来どこかで終わるけど、今はまだ終わってないと思う」という表明的なもの (既に終わっている時もある) 色んな言語で実装されているが、 PHP はライブラリレベルで実装 `function async(\Closure $callback): Future`
Future だったり Promise だったりする(概念が違うが似た系統)
await? async なクロージャが完了するまで待つ `$results = await($futures)` 複数のクロージャが全て完了するまで待つことも出来る JavaScript の変遷をたどると分かりやすい SoftwareDesign
2023年9月号に詳しく載ってます! (他人の記事を勝手に宣伝) https://gihyo.jp/magazine/SD/archive/2023/202309
heavyrain
heavyrain での非同期処理 - ほとんどの処理は HTTP レスポンスが来るまでの待機時間 - 同期処理すると、 CPU が暇
- 暇している間に別のリクエストを実行したい - そこで「非同期」処理 - シングルスレッドで「同時に x リクエスト」出来るようにする!
目指せ「1,000 並行」 extension なしだと「1,024 ファイルディスクリプタ」が限界値 ディスクリプタ数が増えると線形に遅くなるので実際そこまではいかなさそう extension を入れるともっと増やせる(最大はエフェメラルポート数くらい?) 現状だと amphp/ext-uv
が比較的アクティブにメンテされている node.js でも使われていた libuv を使った PHP 拡張
まずは「 HTTP シナリオ」を書けること リクエストとレスポンスの連なり(シナリオ)を表現できる必要がある POST /register -> POST /login ->
GET /me -> POST /post -> … - HTTP リクエストを送る - 前のレスポンスのデータを使う - 途中暗号化や認証を行えるようにする(ミドルウェア) - 1人のユーザーの一連のシナリオをスクリプトに変換する
None
ClientInterface - 簡単に HTTP リクエストを実行出来る API を定義 - PSR-7 互換
- Locust や k6 などを参考にした
AssertableResponseInterface - assertion も出来るし json body も取得出来る便利な Response API -
これも PSR-7 互換
MiddlewareInterface - リクエスト間で共通の処理を行える API - これも PSR-7 互換 - 暗号化(ボディ改変)・認証(ヘッダ改変)などを行える
ExecutorInterface - 実際に「シナリオを無限に実行し続ける」 API - OS Signal などで途中でキャンセル出来る - ここで「非同期」を発動!
AmphpExecutor 非同期処理のコア部分の実装 ループでたくさん並行に 実行していく TODO は色々あるが ベースは大体これ
Heavyrain の未来 - 「シナリオテスター」として 1 並列でシナリオが一通り動く - Ramp-up(ちょっとずつ同接が増えていく) の仕組み -
数万 rps, 数十万 rps の負荷をかけれるようになる - 複数マシンを使った 分散負荷かけ環境 - OpenAPI 3.0 から ClientInterface 実装を自動生成 - HARReporter によるシナリオ可視化 - Locust のような Web GUI - Amphp の詳細は PHPCon 2023(東京) で話します!!
次は東京で で会いましょう!
北海道でも 会いましょう!
https://www.infiniteloop.co.jp