プロダクション

プロダクション環境用の構成のためにキャッシュの設定やスクリプトの変更を行います。

bootファイル

コンテキストがprod-で始まるとアプリケーションオブジェクト$appがキャッシュされます。 キャッシュドライバーは環境に応じてApcCacheFilesystemCacheが自動選択されます。

$context = 'prod-app';
require dirname(dirname(__DIR__)) . '/bootstrap/bootstrap.php';

キャッシュの設定

ProdModule

BEAR.Packageのプロダクション用のモジュールProdModuleはwebサーバー1台を前提にしているApcCacheになっています。 webサーバー1台でキャッシュを全てApcで使う場合にはそのまま使用できます。

複数のWebサーバーを構成するためには共有のキャッシュストレージを設定する必要があります。 この場合、アプリケーション固有のProdModulesrc/Module/ProdModule.phpに用意して、 サーバー間で共有するコンテンツ用キャッシュDoctrine\Common\Cache\CacheProvider:@BEAR\RepositoryModule\Annotation\Storageインターフェイスとサーバー単位のキャッシュDoctrine\Common\Cache\Cacheインターフェイスを束縛します。

namespace BEAR\HelloWorld\Module;

use BEAR\RepositoryModule\Annotation\Storage;
use BEAR\Package\Context\ProdModule as PackageProdModule;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\CacheProvider;
use Ray\Di\AbstractModule;
use Ray\Di\Scope;

use Doctrine\Common\Cache\ApcCache;

class ProdModule extends AbstractModule
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $cache = ApcCache::class;
        // 共有キャッシュ
        $this->bind(CacheProvider::class)->annotatedWith(Storage::class)->to($cache)->in(Scope::SINGLETON);
        // サーバー単位のキャッシュ
        $this->bind(Cache::class)->to($cache)->in(Scope::SINGLETON);

        // ProdModule パッケージのインストール
        $this->install(new PackageProdModule);
    }
}

@StorageとアノテートされたCacheインターフェイスは、クエリーリポジトリーのためのものでWebサーバーで共有されるストレージです。

複数のWebサーバーでApcCacheを指定することはできないので、 Redisを指定するか、永続化可能な他のストレージを使ったアダプターを作成して束縛します。 (memcachedも指定できますが、メモリなので容量と揮発性に注意する必要があります。)

HTTP Cache

キャッシュ可能(@Cacheable)とアノテートしたリソースはエンティティタグETagを出力します。

このETagを使ってリソースに変更が無い時は自動で適切な304 (Not Modified)のレスポンスコードを返すことができます。 (この時、ネットワークの転送コストだけでなく、CPUコストも最小限のものにします。)

App

HttpCacheをスクリプトで使うためにAppクラスでHttpCacheInjectのtraitを使ってHttpCacheをインジェクトします。

namespace MyVendor\MyApi\Module;

use BEAR\QueryRepository\HttpCacheInject; // この行を追加
use BEAR\Sunday\Extension\Application\AbstractApp;
use Ray\Di\Di\Inject;

class App extends AbstractApp
{
    use HttpCacheInject; // この行を追加
}

bootstrap

次にbootstrap/bootstrap.phprouteのセクションで以下のようにif文を追加して、 与えらたETagのコンテンツに変更がなければ304を返して終了するようにします。

route: {
    $app = (new Bootstrap)->getApp(__NAMESPACE__, $context);
    if ($app->httpCache->isNotModified($_SERVER)) {
        http_response_code(304);
        exit(0);
    }

ETagの更新は自動で行われますが、@Refresh@Purgeアノテーションを使ってリソースキャッシュの破棄の関係性を適切に指定しておかなければなりません。

エクステンション

以下のPECLエクステンションをインストールするとパフォーマンスが最適化されます。

pecl install uri_template
pecl install igbinary

確認

composer show --platform
ext-uri_template    1.0      The uri_template PHP extension

ディプロイ

DeployerのサポートBEAR.Sunday Deployer.php supportをご覧ください。