Nginxを使用してWordpressをキャッシュします。 Nginx および Apache を使用したホスティングでの圧縮とキャッシュの設定 ブラウザーでの Nginx Apache キャッシュ

31.08.2020

Nginx の Web サーバーとリバース プロキシには、非常に強力な HTTP 応答キャッシュ機能が組み込まれています。 ただし、場合によっては十分なドキュメントや例が存在しないため、すべてが期待どおりに簡単かつシンプルになるわけではありません。 たとえば、私の nginx 設定は、いくつかの場所で血で書かれています。 この記事では、この状況を少し改善してみます。

この記事の内容: a) フルページ キャッシュの落とし穴。 b) ローテーションによるキャッシュ。 c) キャッシュされたページに動的な「ウィンドウ」を作成します。

nginx+fastcgi_php を使用していると仮定します。 nginx+apache+mod_php を使用している場合は、ディレクティブ名を fastcgi_cache* から proxy_cache* に置き換えるだけです。

ページを PHP 側でキャッシュするか nginx 側でキャッシュするかを選択する必要がある場合、私は nginx を選択します。 まず、何の問題もなく、「 高負荷」 次に、nginx はキャッシュ サイズを独自に監視し、キャッシュが古くなった場合と、使用頻度の低いデータが削除された場合の両方でキャッシュを消去します。

ページ全体をキャッシュする

サイトのメイン ページが動的に生成されてもほとんど変更されない場合は、それを nginx にキャッシュすることでサーバーの負荷を大幅に軽減できます。 トラフィックが多い場合、キャッシュでも 短期(5 分以内) キャッシュが非常に高速に動作するため、すでにパフォーマンスが大幅に向上しています。 わずか 30 秒間ページをキャッシュするだけでも、動的データ更新を維持しながら大幅なサーバー負荷が発生します (多くの場合、30 秒に 1 回の更新で十分です)。

たとえば、次のようにメイン ページをキャッシュできます。

Fastcgi_cache_path /var/cache/nginx レベル = key_zone=wholepage:50m; ...server ( ... location / ( ... fastcgi_pass 127.0.0.1:9000; ... # キャッシュを有効にし、キャッシュ キーを慎重に選択します。 fastcgi_cache Wholepage; fastcgi_cache_valid 200 301 302 304 5m; fastcgi_cache_key "$request_method|$ http_if_modified_since |$http_if_none_match|$host|$request_uri"; # 異なるユーザーが同じセッション Cookie を受信しないようにします。 fastcgi_hide_header "Set-Cookie"; # キャッシュに関係なく、 # nginx にページを強制的にキャッシュさせますPHP で設定されたヘッダー fastcgi_ignore_headers "Cache-Control" "Expires" ) )

この設定のすべての行は血で書かれていると言っても過言ではありません。 ここにはたくさんあります 落とし穴、全部見てみましょう。

fastcgi_cache_path: デバッグのしやすさも重要です

fastcgi_cache_path /var/cache/nginx レベル = key_zone=wholepage:50m;

fastcgi_cache_path ディレクティブで、レベルに「空」の値を設定しました。 これによりパフォーマンスは若干低下しますが (ファイルはディレクトリに分割せずに /var/cache/nginx に直接作成されます)、キャッシュの問題のデバッグと診断がはるかに簡単になります。 信じてください、/var/cache/nginx に複数回アクセスして、そこに何が保存されているかを確認する必要があります。

fastcgi_cache_valid: 304 応答コードもキャッシュします

fastcgi_cache_valid 200 301 302 304 5m;

fastcgi_cache_valid ディレクティブでは、キャッシュを強制するだけでなく、 標準コード 200 OK、301 Moved Permanently、302 Found ですが、304 Not Modified もあります。 なぜ? 304 が何を意味するのかを思い出してください。次の 2 つのケースで空の応答本文が発行されます。

  • ブラウザーが、日付が「Last-Modified: date」応答ヘッダーの値以上である「If-Modified-Since: date」ヘッダーを送信した場合。 それらの。 クライアントは「日付以降に新しいバージョンはありますか?」と尋ねます。 そうでない場合は、304 を返して帯域幅を節約してください。 ある場合は、ページの本文を教えてください。」
  • ブラウザが「If-None-Match: hash」ヘッダーを送信した場合、そのハッシュは応答ヘッダー「ETag: hash」の値と一致します。 それらの。 クライアントはこう尋ねます。 現在のバージョン前回リクエストしたページから何ページですか? そうでない場合は、304 を返して帯域幅を節約してください。 もしそうなら、ページの本文を教えてください。」

どちらの場合も、Last-Modified または ETag は nginx キャッシュから取得される可能性が高く、チェックは非常に高速です。 特に 200 応答を受信するクライアントはキャッシュから応答を受け取るという事実を考慮すると、これらのヘッダーを生成するスクリプトのためだけに PHP を「プル」する必要はありません。

fastcgi_cache_key: 依存関係を慎重に処理します

fastcgi_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";

fastcgi_cache_key ディレクティブの値には特別な注意が必要です。 このディレクティブの最小動作値を指定しました。 右に一歩、左に一歩進むと、場合によってはキャッシュから「間違った」データを受け取り始めることになります。 それで:

  • $request_method への依存が必要な理由は... HEAD リクエストはインターネット上で非常に一般的です。 HEAD リクエストに対する応答には本文が含まれることはありません。 $request_method への依存を削除すると、誰かが HEAD メソッドを使用してメイン ページをリクエストし、空のコンテンツが GET 経由で返される可能性があります。
  • $http_if_modified_since への依存関係は、通常の GET リクエストを行うクライアントに 304 Not Modified 応答を含むキャッシュが誤って返されないようにするために必要です。 そうしないと、クライアントはキャッシュから空の応答を受け取る可能性があります。
  • $http_if_none_match についても同様です。 クライアントに白紙のページを配信しないように保険をかけなければなりません。
  • 最後に、$host と $request_uri への依存関係にはコメントは必要ありません。
fastcgi_hide_header: セキュリティ問題の解決

fastcgi_hide_header "Cookie の設定";

fastcgi_hide_header ディレクティブは非常に重要です。 これがないと、重大なセキュリティ リスクが発生します。ユーザーは、キャッシュ内のセッション Cookie を介して他の人のセッションを取得できます。 (確かに、nginx の最新バージョンでは、この要素が自動的に考慮されるように何らかの処理が行われています。) これがどのようにして起こるか理解していますか? Vasya Pupkin がサイトを訪問し、セッションとセッション Cookie を受け取りました。 その時点でキャッシュが空であることが判明すると、Vasina の Cookie がキャッシュに書き込まれます。 その後、別のユーザーが来て、キャッシュから応答を受け取り、その中に Vasya の Cookie が含まれていました。 それは彼のセッションも意味します。

もちろん、「メイン ページで session_start() を呼び出さないようにしましょう」ということもできます。そうすれば、Cookie に問題は発生しません。 理論的にはこれは正しいですが、実際には この方法非常に不安定です。 セッションは「遅延」して開始されることが多く、コードの一部がセッションへのアクセスを必要とする関数を「誤って」呼び出すだけで、セキュリティ ホールが発生します。 そして、セキュリティとは、過失により特定の技術に穴が現れる可能性がある場合、その技術は定義上「漏洩している」とみなされるようなものです。 さらに、セッション Cookie 以外にも Cookie があります。 また、キャッシュに書き込む必要もありません。

fastcgi_ignore_headers: タイプミスがあるときにサイトを負荷から「横たわらせ」ないようにする

fastcgi_ignore_headers "キャッシュ制御" "期限切れ";

nginx サーバーは、PHP が発行する Cache-Control、Expires、および Pragma ヘッダーに注意を払います。 ページをキャッシュする必要がない (またはすでに期限切れである) と判断された場合、nginx はそのページをキャッシュ ファイルに書き込みません。 この動作は論理的であるように見えますが、実際には多くの困難を引き起こします。 したがって、これをブロックします。fastcgi_ignore_headers のおかげで、ヘッダーに関係なく、すべてのページのコンテンツがキャッシュ ファイルに含まれます。

これらの困難は何ですか? これらもセッションと session_start() 関数に関連しており、PHP ではデフォルトでヘッダー「Cache-Control: no-cache」と「Pragma: no-cache」を設定します。 この問題には 3 つの解決策があります。

  • キャッシュが必要なページでは session_start() を使用しないでください。 この方法の欠点の 1 つは上ですでに説明しました。必要なのは 1 回の不注意な動きだけであり、キャッシュされたホームページへの 1 秒あたり数千のリクエストを受信するサイトは、キャッシュが無効になると即座にクラッシュします。 2 番目の欠点は、nginx 構成と PHP コードの 2 つの場所でキャッシュ ロジックを管理する必要があることです。 それらの。 このロジックは、システムのまったく異なる部分に「分散」されます。
  • ini_set ("session.cache_limiter", "") を設定します。 これにより、PHP はセッションを操作するときにキャッシュを制限するヘッダーを強制的に無効にします。 ここでの問題は同じです。つまり、キャッシュ ロジックの「不鮮明化」です。理想的には、すべてのキャッシュを 1 か所から管理したいからです。
  • fastcgi_ignore_headers を使用してキャッシュ ファイルに書き込むときに、キャッシュ無効ヘッダーを無視します。 これは双方にメリットのあるソリューションのように思えるので、お勧めします。
ローテーションによるキャッシュ

静的なホームページはそれほど魅力的なものではありません。 サイト上に大量の資料があり、ホームページがそれらの資料の一種の「ショーケース」として機能する場合はどうすればよいでしょうか? このような「ショーケース」では、異なるユーザーが異なるものを見ることができるように、「ランダムな」素材を表示すると便利です(1 人のユーザーでも同じものを受け取ることができます)。 新しいコンテンツ、ブラウザでページをリロードします)。

この問題の解決策は、ローテーションを使用したキャッシュです。

  • スクリプトがメイン ページの要素を正直に生成するように強制します。 ランダムな順序、データベースに対して必要なクエリを実行します (たとえ遅い場合でも)。
  • 次に、1 つではなく、たとえば 10 個のページ バリエーションをキャッシュに保存します。
  • ユーザーがサイトにアクセスすると、これらのオプションのいずれかが表示されます。 この場合、キャッシュが空であればスクリプトが起動され、そうでなければ結果がキャッシュから返されます。
  • キャッシュの有効期限を短く (たとえば 1 分) 設定し、日中はさまざまなユーザーがサイトのすべてのマテリアルを「視聴」できるようにします。
  • その結果、ジェネレーター スクリプトへの最初の 10 リクエストは「正直に」実行され、サーバーに「ロード」されます。 ただし、キャッシュ内に「定着」し、1 分以内にすぐに発行されます。 サイトの訪問者が増えるほど、生産性は大幅に向上します。

    以下は、ローテーションによるキャッシュを実装する nginx 構成の一部です。

    Fastcgi_cache_path /var/cache/nginx レベル = key_zone=wholepage:50m; perl_set $rand "sub ( return int rand 10 )"; ...server ( ... location / ( ... fastcgi_pass 127.0.0.1:9000; ... # キャッシュをオンにし、キャッシュ キーを慎重に選択します。 fastcgi_cache Wholepage; fastcgi_cache_valid 200 301 302 304 1m; fastcgi_cache_key "$rand| $request_method |$http_if_modified_since|$http_if_none_match|$host|$request_uri"; # 異なるユーザーが同じセッション Cookie を受信しないようにします。 fastcgi_hide_header "Set-Cookie"; # どのような場合でも、nginx にページを強制的にキャッシュします。キャッシュヘッダー、PHP で設定されます fastcgi_ignore_headers "Cache-Control" "Expires"; # 毎回ブラウザーにページを強制的にリロードします (回転のため)、post-check=0、pre-check=0"; fastcgi_hide_header "Pragma" ; add_header Pragma "no-cache"; # 常に新しい Last-Modified を発行します。 # 注意: add_header Last-Modified $sent_http_Expires;

    前の例と比較すると、location にさらに 6 つのディレクティブを追加する必要があることに気づくかもしれません。 それらはすべてとても重要です! しかし、先走らず、すべてを順番に検討しましょう。

    perl_set: ランダマイザーの依存関係

    perl_set $rand "sub ( return int rand 10 )";

    perl_set ディレクティブを使用すると、すべてが簡単になります。 使用すると、nginx が組み込み Perl インタープリターの関数を呼び出す変数を作成します。 nginx の作者によると、これはかなり高速な操作であるため、「一致を節約」することはありません。 この変数は、各 HTTP リクエストで 0 から 9 までのランダムな値を受け取ります。

    fastcgi_cache_key: ランダマイザーの依存関係

    fastcgi_cache_key "$rand|$request_method|...";

    ここで、ランダマイザー変数をキャッシュ キーに混合します。 結果は10です さまざまなキャッシュ同じ URL にアクセスします。これが必要なものです。 キャッシュミス時に呼び出されたスクリプトが要素を生成するため、 ホームページランダムな順序で、10 種類のメイン ページを取得します。それぞれが 1 分間「存続」します (fastcgi_cache_valid を参照)。

    add_header: ブラウザのキャッシュを強制的に無効にします fastcgi_hide_header "Cache-Control"; add_header キャッシュ制御 "no-store、no-cache、must-revalidate、post-check=0、pre-check=0"; fastcgi_hide_header "プラグマ"; add_header プラグマ "no-cache";

    上で、nginx は PHP スクリプトによって発行されたキャッシュ ヘッダーの影響を受けやすいと述べました。 PHP スクリプトがヘッダー「Pragma: no-cache」または「Cache-Control: no-store」を返した場合 (および他のヘッダー、たとえば「Cache-Control: do not store, do not issue, I am notここに - あった、私はそれを言っていません、誰の帽子です」)の場合、nginx は結果をキャッシュ ファイルに保存しません。 この動作を特に抑制するには、fastcgi_ignore_headers を使用します (上記を参照)。

    「Pragma: no-cache」と「Cache-Control: no-cache」の違いは何ですか? そのプラグマのみが HTTP/1.0 のレガシーであり、古いブラウザとの互換性のためにサポートされるようになりました。 HTTP/1.1 はキャッシュ制御を使用します。

    ただし、ブラウザーにもキャッシュがあります。 また、場合によっては、ブラウザがサーバーにページをレンダリングするリクエストを送信しようとしないこともあります。 代わりに、独自のキャッシュから取得します。 なぜなら ローテーションがありますが、この動作は私たちにとって不便です。結局のところ、ユーザーがページにアクセスするたびに、ユーザーには新しいデータが表示される必要があります。 (実際、1 つのオプションをキャッシュしたい場合は、Cache-Control ヘッダーを試してみることができます。)

    add_header ディレクティブは、キャッシュ無効ヘッダーをブラウザーに送信します。 このヘッダーが誤って増殖するのを防ぐために、まず HTTP 応答から、PHP スクリプトがそこに書き込んだもの (および nginx キャッシュに書き込まれたもの)、つまり fastcgi_hide_header ディレクティブを削除します。 結局のところ、nginx 構成を作成するとき、PHP がそこに出力することをどのように考えるかはわかりません (そして、session_start() が使用されている場合は、間違いなくそれを考えるでしょう)。 独自の Cache-Control ヘッダーを公開したらどうなるでしょうか? 次に、それらのうちの 2 つが存在します。PHP のものと、add_header によって追加したものです。

    有効期限と最終更新日: ページのリロード有効期限が -1 であることを保証します。 # 注意!!! この期限切れラインは必要です! add_header 最終更新日 $sent_http_Expires;

    もう 1 つのトリック: Last-Modified を現在時刻と等しくなるように設定する必要があります。 残念ながら、nginx には現在の時刻を格納する変数がありませんが、expires -1 ディレクティブを指定すると魔法のように変数が表示されます。

    現在 (2009 年 10 月) 文書化されていませんが、nginx はクライアントに送信される XXX 応答ヘッダーごとに $sent_http_XXX 形式の変数を作成します。 私たちはそのうちの1つを使用しています。

    このタイトルを現在の時刻に設定することがなぜそれほど重要なのでしょうか? とてもシンプルです。

  • PHP がヘッダー「Last-Modified: some_date」を出力すると想像してみましょう。
  • このヘッダーは nginx キャッシュ ファイルに書き込まれ (確認できます。この例では、ファイルは /var/cache/nginx に保存されています)、クライアント ブラウザーに送信されます。
  • ブラウザはページとその変更日を記憶します...
  • ... したがって、次回ユーザーがサイトにアクセスすると、HTTP リクエストには質問ヘッダー「If-Modified-Since: some_date」が含まれることになります。
  • nginxは何をするのでしょうか? キャッシュからページを取得し、そのヘッダーを解析し、Last-Modified と If-Modified-Since を比較します。 値が一致する場合 (または最初の値が 2 番目の値より小さい場合)、nginx は空の本文を含む「304 Not Modified」応答を返します。 そして、ユーザーには回転は表示されません。ユーザーは、以前にすでに見たものを受け取ることになります。
  • 実際、大きな問題は、Last-Modified と Cache-Control no-cache の両方が存在する場合にブラウザがどのように動作するかということです。 If-Modified-Since リクエストを実行しますか? どうやら さまざまなブラウザここでは違う行動をします。 実験。

    Last-Modified を手動で設定する理由はもう 1 つあります。 実際のところ、PHP 関数 session_start() は強制的に Last-Modified ヘッダーを発行しますが、その中に最初に制御を受け取った PHP ファイルの変更時刻が示されています。 したがって、サイト上のすべてのリクエストが同じスクリプト (フロント コントローラー) に送信される場合、Last-Modified はほとんどの場合、この 1 つのスクリプトの変更時刻と等しくなりますが、これは完全に間違っています。

    キャッシュされたページ内の動的な「ウィンドウ」

    最後に、キャッシュの観点から役立つテクニックを 1 つ紹介します。 サイトのメイン (またはその他の) ページをキャッシュしたいが、動的である必要がある 1 つの小さなブロックが邪魔になる場合は、SSI を使用するモジュールを使用します。

    ページの動的である必要がある部分に、次の「HTML コメント」を挿入します。

    nginx キャッシュの観点からは、このコメントはプレーンテキストです。 コメントとしてキャッシュ ファイルに保存されます。 ただし、後でキャッシュを読み取るときに、nginx SSI モジュールが起動して動的 URL にアクセスします。 もちろん、このブロックの内容を出力する PHP ハンドラーが /get_user_info/ に存在する必要があります。

    そしてもちろん、このページまたはサーバー全体に対しても SSI を有効にすることを忘れないでください。

    SSI include ディレクティブには、もう 1 つ、非常に重要な機能があります。 大切な財産。 このようなディレクティブがページ上で複数見つかると、それらはすべて並列モードで同時に処理され始めます。 したがって、ページ上に 4 つのブロックがあり、それぞれの読み込みに 200 ミリ秒かかる場合、ユーザーは合計でページを 800 ミリ秒ではなく 200 ミリ秒で受信します。

    クライアント側のデータ キャッシュ - 特定の種類のデータの 1 回限りのダウンロードを構成し、それをクライアントのメモリに保存する機能。 nginx ブラウザまたは別のサーバーをキャッシュすると、からのリクエストの数を減らすことができます。 クライアントマシン、その結果、負荷が増加し、サイトの読み込み速度も向上します。

    それらの。 クライアントがサイト ページにアクセスします。サーバーがリクエストを処理し、生成されたページが特定のヘッダーとともにクライアントに送信されます。 ブラウザは情報をローカルに保存し、再度要求されたときに情報を返します。

    画像はキャッシュされます CSS スタイルそしてJavaScript。 Nginx ブラウザーのキャッシュは、Cache-control ヘッダーを追加することで実装されます。

    ヘッダーでは、サービス情報がサーバーからクライアント ブラウザーに送信され、ブラウザーはそこから、特定の種類のデータを保存する必要がある時期と、それをメモリ内に保持する期間を学習します。

    Nginx ブラウザのキャッシュ

    Nginx 設定ファイルでは、次のように JS/CSS キャッシュが有効になっています (他の拡張機能が追加されています - 実際には、それらをすべてキャッシュすることをお勧めします)。

    サーバー (

    location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt)$ (
    最大有効期限が切れます。
    ルート /home/website/example.com/;
    }

    }

    最大期限が切れるということは、TTL が無限に設定されており、サーバー上のファイルが変更されても、繰り返しリクエストが送信されないため、クライアントはそれを知ることができないことを意味します。

    期限切れ (このヘッダーについては後述します) はブラウザがキャッシュを更新するタイミングを決定し、値は秒単位で設定されます。

    通常、有効期限の最大値はサーバー構成で設定され、次にアプリケーションで CSS ファイルと JS ファイルを接続するときにそれらのバージョンが決定され、コンテンツが更新されるたびに変更される必要があります。

    アプリケーションレベルのキャッシュヘッダーの指定

    この場合、サーバーはそれぞれのメッセージを受け入れます。 新しいバージョン新しいファイルが追加されたため、それがキャッシュされます。

    Cache-Control とともに、Expires ヘッダーが指定されることがよくあります。ブラウザーが既存のキャッシュをリセットする日時を強制します。 次回ユーザーが連絡すると、更新されたデータが再びキャッシュにロードされます。

    オプションの HTTP Expires ヘッダーは、ブラウザーがキャッシュを更新する日時を指定します (ヘッダーは一緒に使用できます。両方のヘッダーを使用すると、Expires の値は低くなります)。

    両方のヘッダーを次のように指定できます。 プログラムコードアプリケーションレベルで。

    PHP でのキャッシュの有効化

    ほとんどの Web プロジェクトは PHP 言語で記述されており、PHP では、Cache-control および Expires HTTP ヘッダーが次のように設定されます。

    それから何度か質問してください このファイル CURL または Web ブラウザ経由で。

    root@server:~#curl http://localhost/time.php;echo
    1382986152

    1382986152
    root@server:~#curl http://localhost/time.php;echo
    1382986152

    キャッシュが適切に行われている場合、すべてのリクエストのタイムスタンプは一致します (応答がキャッシュされているため)。

    このクエリのキャッシュを見つけるには、キャッシュ ライトバックを実行する必要があります。

    root@server:~# ls -lR /etc/nginx/cache/
    /etc/nginx/キャッシュ/:
    合計0
    drwx------ 3 www-data www-data 60 10月28日 18:53 e
    /etc/nginx/キャッシュ/e:
    合計0
    drwx------ 2 www-data www-data 60 10月28日 18:53 18
    /etc/nginx/cache/e/18:
    合計 4
    -rw------ 1 www-data www-data 117 10月28日 18:53

    次のことを示す X-Cache ヘッダーを追加することもできます。 このリクエストキャッシュから処理されたか (X-Cache HIT)、または直接処理されました (X-Cache MISS)。

    サーバー ( ) ディレクティブの上に、次のように入力します。

    add_header X キャッシュ $upstream_cache_status;

    Nginx サービスを再起動し、curl を使用して詳細なリクエストを発行して、新しいヘッダーを確認します。

    root@server:~#curl -v http://localhost/time.php
    * localhost ポート 80 (#0) に connect() しようとしています
    * 127.0.0.1 を試しています...
    *接続されています
    ※ローカルホスト(127.0.0.1)のポート80(#0)に接続
    > /time.php HTTP/1.1 を取得
    > ユーザーエージェント:curl/7.26.0
    > ホスト: ローカルホスト
    > 受け入れる: */*
    >
    * HTTP 1.1 以降、永続的な接続、パイプラインをサポート
    < HTTP/1.1 200 OK
    < Server: nginx
    < Date: Tue, 29 Oct 2013 11:24:04 GMT
    < Content-Type: text/html
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < X-Cache: HIT

    スクレイピングする URL を指定して、このファイルに POST リクエストを送信します。

    カール -d "url=http://www.example.com/time.php" http://localhost/purge.php

    スクリプトは、キャッシュがクリアされたかどうかに応じて true または false を出力します。 このスクリプトをキャッシュから必ず除外し、アクセスを制限することも忘れないでください。

    タグ: 、

    キャッシュは、すぐにアクセスできるストレージ メディア (キャッシュ、キャッシュ) 上にデータのコピーを作成するテクノロジーまたはプロセスです。 簡単に言うと、Web サイト構築の現実に当てはめると、これは、PHP スクリプト (または Perl、ASP.net など) を使用して生成される、ページまたはその一部の静的 HTML コピーの作成となります。サイトの CMS がどの言語で記述され、どの言語でディスクに保存されるか ラムまたはブラウザ内で部分的にさえも表示されます (以下で詳しく説明します)。 クライアント (ブラウザー) からページに対するリクエストが発生すると、スクリプトでページを再構築する代わりに、ブラウザーはその既製のコピーを受け取ります。完成したページは、新たに作成するよりも時間がかかりません (大幅に短縮される場合もあります)。

    Web サイトでキャッシュを使用する理由は何ですか?
    • ホスティングの負荷を軽減するには
    • サイトのコンテンツをブラウザにすばやく表示するには

    どちらの議論もコメントは不要だと思います。

    Web サイトのキャッシュの短所と悪影響

    奇妙なことに、Web サイトのキャッシュには欠点もあります。 まず第一に、これは、操作中にコンテンツが動的に変化するサイトに当てはまります。 多くの場合、これらはコンテンツまたはその一部を提供するサイトです。 AJAXを使用する。 一般に、AJAX キャッシュも可能であり、必要ですらありますが、これは別の議論のトピックであり、後で説明する伝統的に使用されているテクノロジには関係ありません。
    また、登録ユーザーにとっては、サイト要素を操作するときに永続的なキャッシュが問題になる可能性があるため、問題が発生する可能性があります。 ここでは、原則としてキャッシュが無効になっているか、オブジェクト キャッシュが使用されます。 個々の要素ウェブサイト: ウィジェット、メニューなど。

    Web サイトでキャッシュを設定する方法

    まず、Web サイトのコンテンツをキャッシュするために従来どのようなテクノロジーが使用されているかを把握する必要があります。
    全て 可能な方法 3つのグループに分けることができます

    サーバー側のキャッシュ NGINX によるキャッシュ htaccess (Apache) によるキャッシュ

    .htaccess にのみアクセスでき、運用サーバーが Apache のみである場合は、gzip 圧縮や Expires ヘッダーなどの技術を使用して、ブラウザー キャッシュを利用できます。

    対応する MIME ファイル タイプの gzip 圧縮を有効にする

    AddOTPUTFILTERBYTYPE DEFLATE TEXT/HTML AddOTPUTPULTERBYTYPE Deflate Text JavaScript Application/X-JavaScript AddOTPUTFILTERBYTYPE Deflate Text/XML Application/XHTML+XML Application/RSS+XML AddUTPUTPUTFILTERBYT Ype Deflate Application/Json Addoutputfilterbytype DEFLATE application/vnd.ms-fontobject application/x-font- ttf フォント/opentype 画像/svg+xml 画像/x-icon

    静的ファイルの Expires ヘッダーを 1 年間 (365 日) 有効にします。

    ExpiresExpiresDefault でアクティブ「アクセスプラス 365 日」

    Memcached によるキャッシュ PHP アクセラレータによるキャッシュ

    サイト エンジンが PHP で書かれている場合、サイトのページが読み込まれるたびに、PHP スクリプトが実行されます。コード インタープリターは、プログラマーが書いたスクリプトを読み取り、そこからマシンが理解できるバイトコードを生成し、それを実行して、結果が生まれます。 PHP アクセラレータは、コンパイルされたコードをメモリまたはディスクにキャッシュすることでバイトコードの定常的な生成を排除し、それによってパフォーマンスを向上させ、PHP の実行にかかる時間を短縮します。 現在サポートされているアクセラレータには次のものがあります。

    • PHP 用 Windows キャッシュ拡張機能
    • Xキャッシュ
    • Zend OPcache

    PHP バージョン 5.5 以降にはすでに Zend OPcache アクセラレータが組み込まれているため、アクセラレータを有効にするには、PHP バージョンを更新するだけで済みます。

    サイト側のキャッシュ

    一般に、これは、ページの静的な HTML コピーを作成するサイトの CMS の機能を指します。 ほとんどの一般的なエンジンとフレームワークにはこの機能があります。 個人的に、私は Smarty や WordPress と仕事をしたことがあるので、彼らが素晴らしい仕事をすることを保証できます。 元の WordPress にはそのままではキャッシュ機能がありません。これは、わずかに読み込まれたプロジェクトに必要ですが、キャッシュ用の人気のあるプラグインが多数あります。

  • 、静的な Web サイト ページの生成を担当します。
  • Hyper Cache。基本的には以前のプラグインと同じように機能します。
  • DBキャッシュ。 作業の本質は、クエリをデータベースにキャッシュすることです。 また、とても 便利な機能。 前の 2 つのプラグインと組み合わせて使用​​できます。
  • W3 合計キャッシュ。 デザートとして取っておきましたが、これは WordPress で私のお気に入りのプラグインです。 これにより、敷地は巨大なバスからレーシングカーに変わります。 その大きな利点は、いくつかのキャッシュ オプション (静的、アクセラレータ、Memcached、データベース クエリ、オブジェクトとページのキャッシュ)、コードの連結と縮小 (CSS、JavaScript ファイルのマージと圧縮、スペースの削除による HTML 圧縮) などの膨大な機能セットです。 、 CDN を使用するなどなど。
  • 何と言っても、適切な CMS を使用すれば、高品質のキャッシュがほぼそのまま使用できるようになります。

    ブラウザ (クライアント) 側のキャッシュ、ヘッダーのキャッシュ

    ブラウザのキャッシュが可能なのは、自尊心のあるブラウザがキャッシュを許可し、奨励しているためです。 これは、サーバーがクライアントに提供する次の HTTP ヘッダーが原因である可能性があります。

    • 有効期限が切れます。
    • キャッシュ制御: 最大経過時間;
    • 最終更新日。
    • Eタグ。

    これらのおかげで、サイトに繰り返しアクセスするユーザーは、ページの読み込みにほとんど時間を費やしません。 キャッシュ ヘッダーは、キャッシュされたすべての静的リソース (テンプレート ファイル、画像、 JavaScriptファイル CSS (利用可能な場合)、PDF、オーディオ、ビデオなど。
    静的データが少なくとも 1 週間、1 年以内、できれば 1 年間保存されるようにヘッダーを設定することをお勧めします。

    有効期限が切れます

    Expires ヘッダーはキャッシュの有効期間を制御し、ブラウザーはサーバーに新しいバージョンを要求せずにキャッシュされたリソースを使用できます。 これは強力であり、必須であるため、使用することが非常に望ましいです。 タイトルには1週間から1年程度の期間を記載することをお勧めします。 1 年を超えて指定しないほうがよいでしょう。これは RFC ルールに違反します。

    たとえば、NGINX ですべての静的ファイルの有効期限を 1 年 (365 日) に設定するには、コードが NGINX 設定ファイルに存在する必要があります。

    場所 ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ (有効期限は 365 日; )

    キャッシュ制御: 最大経過時間;

    Cache-Control: max-age も同じことを行います。
    広く普及しているため、Cache-Control よりも Expires を使用することをお勧めします。 ただし、ヘッダーに Expires と Cache-Control が同時に存在する場合は、Cache-Control が優先されます。

    NGINX では、Cache-Control は Expires と同じように、expires: 365d ディレクティブを使用して有効になります。

    最終更新日とETag

    これらのヘッダーはデジタル指紋の原理に基づいて機能します。 これは、キャッシュ内の各 URL が独自の一意の ID を持つことを意味します。 Last-Modified は日付に基づいて作成します 最後の変更。 ETag ヘッダーは、任意の一意のリソース識別子 (ほとんどの場合、ファイル バージョンまたはコンテンツ ハッシュ) を使用します。 Last-Modified は、ブラウザがヒューリスティックを使用してキャッシュから要素を要求するかどうかを決定するため、「弱い」ヘッダーです。

    NGINX では、静的ファイルに対して ETag と Last-Modified がデフォルトで有効になっています。 動的ページの場合は、動的ページを指定しないこと、またはページを生成するスクリプトでこれを行うこと、または何よりも適切に構成されたキャッシュを使用することをお勧めします。そうすれば、NGINX がヘッダー自体を処理します。 たとえば、WordPress の場合は、 を使用できます。

    これらのヘッダーを使用すると、ユーザーが明示的にページをリロードするたびに GET リクエストを送信することで、ブラウザーがキャッシュされたリソースを効率的に更新できるようになります。 条件付き GET リクエストは、サーバー上のリソースが変更されない限り完全な応答を返さないため、 完全なクエリこれにより、ホスティングの負荷が軽減され、応答時間が短縮されます。

    Expires と Cache-Control: max-age の同時使用は、Last-Modified と ETag の同時使用が冗長であるのと同様に、冗長です。 Expires + ETag または Expires + Last-Modified を組み合わせて使用​​します。

    静的ファイルの GZIP 圧縮を有効にする

    もちろん、GZIP 圧縮はキャッシュそのものには直接関係しませんが、トラフィックを大幅に節約し、ページの読み込み速度を向上させます。

    サーバーで静的 GZIP を有効にする方法 ( .... gzip on; gzip_disable "msie6"; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application /javascript; ) 静的 GZIP を有効にする方法 .htaccess で gzip 圧縮を有効にするには、ファイルの先頭に次のコードを挿入する必要があります。 AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/ xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript

    Nginx は、特に Web サイトのコンテンツを一時的に保存できるため、Web プロジェクトでよく使用されます。 Nginx では、キャッシュは (他のリポジトリと比較して) セットアップが非常に簡単で、Web サーバーの動作を最適化する良い方法です。

    重荷重に使用します。 キャッシュを使用すると、サイトへの 2 回目以降の呼び出し時にコンテンツをより速く提供できます。 キャッシュに関する Nginx ブログ。

    また、キャッシュサーバーは簡単にクラスタ化できます。

    nginx キャッシュが正しく機能するために、nginx.conf 構成ファイルは、サーバー側でキャッシュされたデータが保存されるディレクトリへのパスを定義し、そのサイズを設定します。

    サーバーのキャッシュとストレージとしての Nginx の使用について説明します。 の方が設定しやすいです。

    Web サーバーは、異なるポート (通常は異なるマシン) 上で 2 つのコピーで起動されます。

    キャッシュ Web サーバーにより負荷が軽減されます。 ページは生成されるとキャッシュに保存され、設定された TTL (存続時間) が期限切れになるまでキャッシュからクライアントに送信されます。 有効期限が切れると、ページが再度生成され、キャッシュにロードされます。これは、サイト訪問者が最新の情報を受け取るために必要です。

    Nginx キャッシュ:設定

    この例では、キャッシュされたデータはサーバー 123.123.123.123 の /var/cache/nginx ディレクトリに保存されます。 最大サイズキャッシュ内のファイル - 128 MB、このバッファが十分でない場合、最もまれに要求されるデータが削除されます

    mcedit /etc/nginx/nginx.conf

    http(
    proxy_cache_path /var/nginx/キャッシュ レベル=1:2 key_zone=all:128m;
    }

    /var/nginx/cache ディレクトリを作成する必要があります

    mkdir -p /var/nginx/cache

    仮想ホストのセットアップ

    ここで必要なのは、キャッシュ用に選択された Nginx でリクエストを受け入れ、それらをメイン サーバーにプロキシすることだけです。

    サーバー (
    聞いてください *:80;

    サーバー名 example.com;
    アクセスログ /var/log/nginx/access.log;

    位置/(

    プロキシパス http://124.124.124.124:80/;
    proxy_set_header ホスト $host;
    プロキシバッファリングがオン。
    proxy_cache すべて;
    proxy_cache_valid 任意の 30m;
    proxy_cache_valid 200 1d;
    proxy_cache_use_stale エラー タイムアウト無効なヘッダーの更新 http_500 http_502 http_503 http_504;

    }

    構成ファイルには、すべてのコンテンツをキャッシュする必要があり、TTL が 30 分に設定されていることが記載されています。

    仮想ホストがアクティブ化される

    アドレス 124.124.124.124 のメイン Nginx サーバー上:

    ここで変更を加える必要はありません。必要に応じて、別のポートで Web サーバーを実行できます。

    mcedit /etc/nginx/sites-availible/example.com

    サーバー (
    聞いてください *:80;
    サーバー名 example.com;
    proxy_read_timeout 200 秒;
    アクセス_ログオフ;

    ルート /var/www/sites/example.com/;

    位置/(
    プロキシパス http://127.0.0.1:8080;
    proxy_set_header ホスト $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    }

    }

    ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled

    構成は、Nginx + PHP-FPM または例のように何でも構いません。

    キャッシュをチェックするために、index.php ファイルを追加します。

    mcedit /var/www/sites/example.com/index.php

    これで、ブラウザ「Works!」からサイトにアクセスできるようになりました。

    リクエストが正常にリダイレクトされていることを示します。

    アドレス 123.123.123.123 のキャッシュ Nginx サーバー上: