動的に生成されたページ(PHP-FPM、NGINX)をキャッシュし、その前にワニスを付けています。これは非常にうまく機能します。
ただし、キャッシュタイムアウトに達すると、次のようになります。
- 新しいクライアントリクエストページ
- ワニスはキャッシュタイムアウトを認識します
- クライアントが待機する
- ワニスはバックエンドから新しいページを取得します
- varnishは新しいページをクライアントに配信します(また、すぐに取得する次のリクエストのためにページもキャッシュされます)
私がしたいのは:
- クライアントリクエストページ
- ワニスはタイムアウトを認識します
- ニスは古いページをクライアントに配信します
- ワニスはバックエンドから新しいページを取得してキャッシュに入れます
私の場合、特に数分からのキャッシュタイムアウトについて話しているときではなく、古い情報が非常に大きな問題を抱えているサイトではありません。
しかし、私はユーザーを罰せずに列に並んで待って、すぐに何かを届けたいとは思いません。それは何らかの方法で可能ですか?
例として、1分間キャッシュするように構成された私のサーバーに対してsiegeを5分間実行した場合の出力例を次に示します。
HTTP/1.1,200, 1.97, 12710,/,1,2013-06-24 00:21:06
...
HTTP/1.1,200, 1.88, 12710,/,1,2013-06-24 00:21:20
...
HTTP/1.1,200, 1.93, 12710,/,1,2013-06-24 00:22:08
...
HTTP/1.1,200, 1.89, 12710,/,1,2013-06-24 00:22:22
...
HTTP/1.1,200, 1.94, 12710,/,1,2013-06-24 00:23:10
...
HTTP/1.1,200, 1.91, 12709,/,1,2013-06-24 00:23:23
...
HTTP/1.1,200, 1.93, 12710,/,1,2013-06-24 00:24:12
...
実行中の何百ものリクエストを省略しまし0.02
た。しかし、未加工のHTMLを2秒近く待たなければならないユーザーがいるのではないかと、私はまだ懸念しています。
ここでもっと上手くできないの?
(私はキャッシュ中にVarnishの送信に遭遇しました、それは同じように聞こえましたが、正確に私がやろうとしていることではありません。)
解決
Shane Maddenの回答には解決策が含まれていましたが、すぐにはわかりませんでした。関連性がないと思ったので質問に含めなかった別の詳細がありましたが、実際にはそうです。
私が現在使用しているCMSソリューションには、ニスデータベースリスナーがあり、コンテンツが変更されたページを禁止するようにニスに通知する機能があります。それはPURGE
あるページを禁止するためにいくつかの正規表現でリクエストを送りました。
要約すると、私が不運なユーザーを獲得した2つのケースがあります。
- ページの通常のニスTTLが期限切れ
- バックエンドユーザーがコンテンツを変更すると、これによりニスにパージリクエストが送信されます
どちらの場合も、「不運な」ユーザーがいます。2番目のケースでは、バックエンドユーザーは通常、変更後にページをチェックするという事実によって緩和されます。必ずしもそうではありません。
それにもかかわらず、2番目のケースでは、ソリューションを作成しました(そうです、この質問は、最初のケースの答えを探すことから始まりました...私の側で不十分に定式化された質問)。
パージリクエストを送信する代わりに、Shanesの提案を使用してVCLを調整し、ワニスデータベースリスナーがにhash_always_miss
設定されたページをフェッチする特別なリクエストを送信できるようにしましたtrue
。
現在のアーキテクチャでは、実際の非同期リクエストを実行する余裕は本当にありませんが、PHPで非同期GETリクエストを作成するにはどうすればよいですか?私は、ページが読み込まれるのを待たずに、ワニスをトリガーしてバックエンドからページを取得してキャッシュするのに十分な、ワニスへのGETリクエストを作成できました。
正味の影響は、データベースリスナーがニスにリクエストを送信し、特定のページをポーリングしている間はリクエストが「不運」になることはありませんでしたが、ニスがバックエンドからページを完全にフェッチすると(300ミリ秒から2秒の範囲になる可能性があります)。突然そこにいた。
私はまだ、通常のTTLがなくなったときに同じ問題を回避する方法を見つける必要がありますが、解決策はShaneが提案するとおりです:wgetを使用してをトリガーするhash_always_miss
ので、リストを取得するのに十分賢くする必要があります更新する必要があるページの数。