PHP 8.3、FPM 8.3.6、Debian 12 のコンテナ。依存パッケージは 180 個ほど、アプリ側のクラスが約 1,400。PSR-4 のまま composer dump-autoload -o で運用していたが、リクエストごとに vendor/composer/autoload_psr4.php の配列を引き、存在しないクラス名のたびに file_exists が走るのが気になっていた。プロファイルは取っていないが、opcache のヒット率が高くても autoload のスタックが上位に残るのが常だった。
やったことは単純で、composer.json に以下を足して classmap を併用させた。
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true,
"apcu-autoloader": true
}
生成は composer dump-autoload -o --classmap-authoritative。classmap-authoritative を入れると PSR-4 のフォールバック探索が無効になり、classmap に無いクラスはその場で「見つからない」と確定する。apcu-autoloader は APCu が有効な FPM でのみ効くので、CLI のバッチでは classmap をそのまま読む。デプロイは composer install --no-dev -o --classmap-authoritative をイメージビルド時に一度だけ実行し、実行時に dump しない。
仕組みとしては、classmap は vendor/composer/autoload_classmap.php の巨大な配列を opcache に載せ、探索を配列参照 1 回で済ませる。代わりに配列そのものがメモリを食う。手元では 1,400 クラスで 1 MB 前後、opcache の shared memory 使用量は数十 MB 増えた。APCu を挟むとプロセスごとのコピーを避けられるが、APCu の領域が小さいと apc.enable_cli 絡みで CLI 側が静かに落ちる。
効かない条件もはっきりしている。classmap-authoritative は実行時に eval や動的 require でクラスを読み込むコードと相性が悪い。うちでは古いプラグイン読み込みが require_once でクラスを後から足しており、classmap に無いため 500 になった。もう一つ、composer install をデプロイ先で走らせる運用だと、classmap がビルド時のファイル一覧に固定されるので、ホットフィックスでファイルを足した瞬間に壊れる。結局、動的読み込みの箇所だけ spl_autoload_register で明示的に登録する形に直した。
同じ構成で classmap-authoritative を外したときと比べて、autoload の所要は体感で減ったが、数字は取っていない。皆さんの環境では、動的読み込みと classmap の折り合いをどう付けていますか。


0 条评论
还没有评论,写下第一条。