概要
LaravelアプリをNginxとphp-fpmで繋げた設定をDocker化して開発していた環境をOctane(OpenSwoole)に移行したときに起きた問題をご紹介します。
移行内容などは、以下の各記事などから前提知識を得てからご覧ください。
問題
LaravelをFROM php:8.2.0-fpm
指定したイメージでコンテナを作り、Nginxのコンテナからngx_http_fastcgi_moduleの設定で疎通できるようにDocker環境を作っていました。
そこでOctaneに移行してNginxとはリバースプロキシでの疎通に変わったことにより、APCuを指定したLaravel Cacheで保存も取得もできない問題が起きました。
APCuの設定は、PHPコンテナを作るDockerfileにRUN pecl install apcu && docker-php-ext-enable apcu
を記述してLaravel Cacheでapc
を指定すれば使用できます。
以下のサンプルでも確認できます。
<?php
namespace App\Service;
class RandomNumberService
{
protected $number;
public function __construct()
{
$this->number = mt_rand(1, 10000);
}
public function getNumber() :int
{
return $this->number;
}
}
<?php
namespace App\Http\Controllers;
use App\Service\RandomNumberService;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Cache;
class SampleController extends Controller
{
public function __construct(
private RandomNumberService $service
){}
public function index(): Response
{
Cache::store('apc')->forever("getNumber", $this->service->getNumber());
$num = Cache::store('apc')->get("getNumber", "-1");
return response('Number:' . $num, Response::HTTP_OK);
}
}
対策
この設定はほとんどの場合、テストかデバッグに使います。 これを設定すると、CLI版PHPでAPCが有効になります。 通常の状態では、CLI リクエストのたびにAPCキャッシュを生成し、 収集し、破棄するのは望ましくありません。しかし、テストシナリオによっては、 CLI版のPHPでAPCを簡単に有効に出来た方が便利な場合があります。
apc.enable_cli=1
をiniファイルにセットするようにDockerfileを調整したところOctane環境でもCache::store('apc')
でキャッシュ機能が正常化しました。
では、なぜCLI有効で正常化したのか調査したところ、Octane環境のSwooleやRoadRunnerなどはプロセス化されたワーカー内部からPHPをCLIで動いているようで、Debugbar for Laravelでログを確認するとphp-fpm環境では"interface":"fpm-fcgi"
となり、Octane環境は"interface":"cli"
と出力されてました。
また採用したOpenSwooleのDockerに関する設定の公式ドキュメントでFROM php:8.2.0-cli
を指定されていることからAPCuを利用するにはCLI有効にする必要(RoadRunnerも同じく)がありました。
まとめ
APCuを何となくで使っていたらハマってしまった罠でした笑汗