🐡

LaravelのConcurrencyファサードで並列処理を簡単に!

2025/02/25に公開

LaravelのConcurrencyファサードで並列処理を簡単に!

Laravel 11.23から導入されたConcurrencyファサードを使うと、複数の独立したタスクを同時に実行でき、アプリケーションのパフォーマンスを向上させることができます。
例えば、外部APIからユーザー情報と注文情報を取得する際、従来は順番にリクエストを送っていましたが、Concurrencyを使えばこれらを並列に処理できます。


Concurrencyファサードの基本

Concurrency::run() メソッドを使うと、複数の処理を並列で実行できます。
以下の例では、ユーザー情報と注文情報を同時に取得しています。

<?php

use Illuminate\Support\Facades\Concurrency;
use Illuminate\Support\Facades\Http;

[$userData, $orderData] = Concurrency::run([
    fn() => Http::get('https://api.example.com/users')->json(),
    fn() => Http::get('https://api.example.com/orders')->json(),
]);

この方法のメリット

  • 処理時間の短縮
    従来の同期処理では、リクエストが順番に実行されるため、合計の処理時間が長くなりがちでした。
    Concurrency::run() を使えば、複数のリクエストを並列実行でき、全体の処理時間を短縮できます。

  • シンプルなコード
    並列処理を実装するために、キューやジョブを使う必要がなく、シンプルなコードで済みます。


Concurrencyの実行ドライバ

Concurrencyファサードでは、処理の方法を選択できます。
デフォルトのprocessのほかに、forksyncといったドライバもサポートされています。

ドライバ 特徴
process デフォルトの並列実行方式
fork spatie/fork を使用し、高速な処理が可能
sync 並列処理せずに同期的に実行

forkドライバを使用する場合は、事前に以下のパッケージをインストールしてください。

composer require spatie/fork

Concurrencyファサードのdriver`メソッドを使用して実行ドライバを変更できます。

use Illuminate\Support\Facades\Concurrency;

// `fork`ドライバを使用
Concurrency::driver('fork')->run([
    fn () => heavyTask1(),
    fn () => heavyTask2(),
]);

// `sync`ドライバを使用
Concurrency::driver('sync')->run([
    fn () => task1(),
    fn () => task2(),
]);

デフォルトのprocessドライバを明示的に指定することも可能です。

Concurrency::driver('process')->run([
    fn () => taskA(),
    fn () => taskB(),
]);

driverメソッドを使用することで、状況に応じた最適な実行方式を選択できます。

Concurrency::defer() でバックグラウンド処理を実行

レスポンスをすぐに返したいが、後処理も並列で実行したい場合は、Concurrency::defer() を使うと便利です。
例えば、メトリクスデータの集計処理をバックグラウンドで行いたい場合、以下のように記述できます。

<?php

use Illuminate\Support\Facades\Concurrency;
use App\Services\Metrics;

Concurrency::defer([
    fn() => Metrics::report('users'),
    fn() => Metrics::report('orders'),
]);

Concurrency::defer() の利点

  • ユーザーに素早くレスポンスを返せる
    処理をバックグラウンドで実行できるため、フロントエンドの待ち時間を短縮できます。

  • 並列実行が可能
    defer()内の複数のタスクも、run()と同じように並列で実行されます。


Laravelダイジェスト

Discussion