web-dev-qa-db-ja.com

Rails環境でCache-Control:max-ageヘッダーを使用してVarnishとブラウザを制御する方法は?

最近、私はRailsアプリケーションスタックにVarnishインスタンスを追加しました。デフォルトの構成のVarnishは、次のようにCache-Controlヘッダーを使用して特定のリソースをキャッシュすることで確信できます。

Cache-Control: max-age=86400, public=true

私は私のコントローラーでexpires_inステートメントを使用してそれを達成しました:

def index
  expires_in 24.hours, public: true
  respond_with 'some content'
end

それはうまくいきました。私が予期していなかったことは、Cache-Controlヘッダーもブラウザーに影響を与えることです。これは、ワニスとユーザーのブラウザの両方が特定のリソースをキャッシュするという問題につながります。リソースはワニスから正しく削除されますが、ブラウザーはmax-ageに達しない限り、リソースを再度要求することはありません。

では、「expires_in」をVarnishと組み合わせて使用​​する必要があるのでしょうか。 Varnishの前にあるNginxまたはApacheインスタンスのCache-Controlヘッダーをフィルタリングすることはできましたが、それは奇妙に思えます。

誰かが私を啓発できますか?

よろしく

22
GeorgieF

これは実際には非常に有効で有効な質問であり、リバースプロキシに関する非常に一般的な質問です。

問題は、Cache-Controlプロパティが1つしかなく、クライアントブラウザー(プライベートキャッシュ)および/またはプロキシサーバー(共有キャッシュ)を対象としていることです。サードパーティのプロキシがコンテンツをキャッシュしないようにして、すべてのリクエストをワニス(またはRailsバックエンド)が処理するようにしたい場合は、適切なCache-Controlを送信する必要がありますVarnishのヘッダー。

バックエンドによって送信されたCache-Controlヘッダーの変更については https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching で詳しく説明されています

2つの異なる角度からソリューションにアプローチできます。 Railsバックエンドでmax-ageを定義する場合、たとえば異なるオブジェクトに異なるTTLを指定する場合は、リンクで説明されている方法を使用できます。上記。

別の解決策は、バックエンドからCache-Controlヘッダーをまったく送信せず、代わりにvarnish vcl_fetch()でオブジェクトの望ましいTTLを定義することです。これが私たちが取ったアプローチです。

デフォルトのTTLワニスの600秒)があり、変更が加えられたときに明確に明示的にパージされるページに対して、より長いTTLを定義します。現在のvcl_fetch()の定義は次のとおりです。

sub vcl_fetch {
  if (req.http.Host ~ "(forum|discus)") {
    # Forum pages are purged explicitly, so cache them for 48h
    set beresp.ttl = 48h;
  }

  if (req.url ~ "^/software/") {
    # Software pages are purged explicitly, so cache them for 48h
    set beresp.ttl = 48h;
  }

  if (req.url ~ "^/search/forum_search_results" ) {
    # We don't want forum search results to be cached for longer than 5 minutes
    set beresp.ttl = 300s;
  }

  if(req.url == "/robots.txt") {
    # Robots.txt is updated rarely and should be cached for 4 days
    # Purge manually as required
    set beresp.ttl = 96h;
  }

  if(beresp.status == 404) {
    # Cache 404 responses for 15 seconds
    set beresp.http.Cache-Control = "max-age=15";
    set beresp.ttl = 15s;
    set beresp.grace = 15s;
  }
}

今回のケースでは、WebバックエンドサーバーからCache-Controlヘッダーを送信しません。

13
Ketola