Closed5

Laravelで外部HTTPリクエストを並列実行する

lightkunlightkun

環境作り

てっとり早く動かしたいので、Laravel Sailで作る

curl -s "https://laravel.build/example-app?with=mysql,redis" | bash

cd example-app && ./vendor/bin/sail up -d

バージョン確認

php --version
PHP 8.3.10 (cli) (built: Aug  2 2024 15:31:15) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.10, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.10, Copyright (c), by Zend Technologies
    with Xdebug v3.3.2, Copyright (c) 2002-2024, by Derick Rethans

php artisan -V
Laravel Framework 11.21.0

dockerコンテナからexitしておく。
http://localhost/ にアクセスしたら、エラーになったのでマイグレーション実行。

 ./vendor/bin/sail php artisan migrate

guzzleを突っ込む

./vendor/bin/sail bash

composer require guzzlehttp/guzzle
lightkunlightkun

Controller作成

routes/web.php
 <?php

+use App\Http\Controllers\GetPoolController;
use Illuminate\Support\Facades\Route;

+Route::get('/', GetPoolController::class);
app/Http/Controllers/GetPoolController.php
+<?php
+
+namespace App\Http\Controllers;
+
+use Carbon\CarbonImmutable;
+use Illuminate\Http\Client\Pool;
+use Illuminate\Support\Facades\Http;
+
+class GetPoolController extends Controller
+{
+    public function __invoke()
+    {
+        $startCarbon = CarbonImmutable::now();
+        $responses = Http::pool(fn (Pool $pool) => [
+            $pool->as('example')->get('https://example.com/'),
+            $pool->as('sleep1')->get('https://httpstat.us/200?sleep=10000'),
+            $pool->as('sleep2')->get('https://httpstat.us/200?sleep=8000'),
+        ]);
+        $endCarbon = CarbonImmutable::now();
+
+        return [
+            'startCarbon' => $startCarbon,
+            'endCarbon' => $endCarbon,
+        ];
+    }
+}

https://httpstat.us はレスポンスを遅延させてくれたり、任意のステータスコードを返してくたりする。結構便利。

https://qiita.com/danishi/items/42d8adf6291515e62284#httpstatus

これで、

の3つに並列実行でリクエストを投げてくれる。
直列だと18秒ちょっと、並列だと10秒ちょっとのはず

lightkunlightkun

実行

http://localhost/ にアクセスすると

        {
            "startCarbon":"2024-08-25T09:42:15.009675Z",
            "endCarbon":"2024-08-25T09:42:25.826834Z"
        }

およそ10秒ちょっと。
想定通りの結果に

lightkunlightkun

追加メモ

https://zenn.dev/yumemi_inc/articles/b0ad60d0cfd306
の方法でxdebugを導入。

$responses['sleep1']->body();でbody取得、$responses['example']->status();でステータスコードの取得もできた。そのため特に処理をする上で困ることはなさそう。

ただし、3つのそれぞれのレスポンスにかかった時間は算出するのは難しいかもしれない。

このスクラップは27日前にクローズされました