web-dev-qa-db-ja.com

キャッシュの最大経過時間とニスESI

ホームページにカスタムブロックを表示する必要があります。このカスタムブロックは、Drupalで管理されていないデータを取得します。 Drupalでこれらのデータが変更されたことを示すイベントは発生しないため、max-age cacheプロパティが適切であり、私にとっては問題ありません。ブロックは期待どおりに表示されますが、問題は、このブロックのキャッシュが期限切れにならないように見えることです。実際には、ブロックは更新されません。

調査の結果、 キャッシュの最大経過時間を0に設定しても、BlockBaseを使用して構築されたブロックに影響がないことがわかりましたか? は、匿名要求に対して最大経過キャッシュプロパティが期待どおりに機能しないことを説明しています。上記のトリガーを追加した後、私の開発環境ではすべてが問題ないように見えました。
本番環境では、以前と同じです。ブロックは更新されません。ホスティングプロバイダーと話していると、ページ全体をキャッシュするためにVarnishが使用され、ESI(Edge Side Include)Varnishが管理する独自のキャッシュロジックでこのブロックをレンダリングします。

私はそれをDrupalでクリーンな方法で実装する方法を本当に知りません。私の最初のアイデアは、コントローラーを使用してブロックマークアップをレンダリングし、必要なキャッシュ制御ヘッダーを強制して応答で返すことです。これは私がそのようなコントローラーのために考えたコードです。

$block_manager = \Drupal::service('plugin.manager.block');
$plugin_block = $block_manager->createInstance('my_block_id');
$buildedBlock = $plugin_block->build();
$renderedBlock = \Drupal::service ('renderer')->render ($buildedBlock);

$response = new Response(
    $renderedBlock,
    Response::HTTP_OK,
    array('content-type' => 'text/html')
);
$response->setSharedMaxAge(60);
return $response;

これを行うのはまったく不潔な方法だと思います。誰かより良い提案方法はありますか?私のコードは機能しますか?

1
Kap

マックスエイジ60秒はフロントページのためにかなり低いです。データは実際に頻繁に更新されますか、それとも更新されただけ更新されますが、通常は毎分発生しませんか?

これを解決する1つの可能なアプローチは、毎分実行されるcronジョブでその外部データをフェッチすることです。変更を検出した場合にのみ、キャッシュタグを無効にします。これにより、フロントページが無効になります。このアプローチは、ほとんどの場合、データが実際にはそれほど変化しない場合に興味深いものです。キャッシュが可能な限り有効だからです。

また、ユーザーが実際にフロントページにアクセスしているときに外部システムに依存しないという利点もあります。ブロックは、cronジョブで更新した状態からデータを配信するだけです。

つまり、max-ageヘッダーに影響を与えたい場合は、独自のResponseサブスクライバーを実装する必要があります。 https://www.drupal.org/project/cache_control_override のようなモジュールを使用することもできますが、さまざまなページを慎重にテストして、予想よりも多くの場所でキャッシュが無効になるかどうかを確認する必要があります。例えば言語切り替えブロックは現在それを行うことができます。

内部ページキャッシュをアンインストールすると、このようなキャッシュできない応答もキャッシュされます。ワニスを使用する場合は必要ありません。

キャッシュタグの無効化を構成してVarnishと統合した場合に限ります。そうでない場合、私の推奨は、内部ページキャッシュモジュールを使用して、デフォルトの外部最大経過時間を非常に短い時間に設定することです。 1分。その後、ワニスはその長い間応答をキャッシュでき、その時間後に内部ページキャッシュに対して再検証します。

3
Berdir