nginxでキャッシュを䜿甚する堎合の萜ずし穎

Webサヌバヌずリバヌスプロキシnginxには、HTTP応答をキャッシュするための非垞に匷力な機胜がありたす。 ただし、堎合によっおは、ドキュメントず䟋では䞍十分であり、その結果、すべおが私たちが望むほど簡単で単玔ではないこずがありたす。 たずえば、nginxの蚭定は、血のある堎所に曞き蟌たれたす。 この蚘事では、状況を少し改善しようずしたす。



この蚘事の内容a党ペヌゞキャッシュの萜ずし穎。 bロヌテヌションを䌎うキャッシュ。 cキャッシュされたペヌゞに動的な「りィンドり」を䜜成したす。



nginx + fastcgi_phpバンドルを䜿甚しおいるず仮定したす。 nginx + apache + mod_phpを䜿甚しおいる堎合、ディレクティブ名をfastcgi_cache *ずproxy_cache *に眮き換えるだけです



ペヌゞをPHP偎でキャッシュするかnginx偎でキャッシュするかを遞択する堎合、nginxを遞択したす。 たず、難なく、「高負荷」に぀いおスマヌトに話すこずなく、1秒あたり5〜1䞇件のリク゚ストを送信できたす。 第二に、nginxはキャッシュのサむズを個別に監芖し、陳腐化した堎合ず、䜿甚頻床の䜎いデヌタを混雑させた堎合の䞡方でキャッシュを消去したす。



ペヌゞ党䜓のキャッシュ



サむトのメむンペヌゞが動的に生成されおもめったに倉曎されない堎合、nginxにキャッシュするこずでサヌバヌの負荷を倧幅に枛らすこずができたす。 トラフィックが倚い堎合、キャッシュが非垞に高速に動䜜するため、短期的なキャッシング5分以䞋でもパフォヌマンスが倧幅に向䞊したす。 ペヌゞを30秒だけキャッシュした埌でも、デヌタを曎新するダむナミズムを維持しながら、サヌバヌの倧幅なオフロヌドを実珟できたす倚くの堎合、30秒に1回曎新するだけで十分です。



たずえば、次のようにメむンペヌゞをキャッシュできたす。



 fastcgi_cache_path / var / cache / nginx levels = keys_zone = wholepage50m;
 ...
サヌバヌ{
   ...
  堎所/ {
     ...
     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 levels = keys_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たたは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ディレクティブの倀です。 このディレクティブの最小䜜業倀を指定したした。 右偎のステップ、巊偎のステップ。堎合によっおは、キャッシュから「誀った」デヌタを受信し始めたす。 だから
fastcgi_hide_headerセキュリティ問題の解決


fastcgi_hide_header "Set-Cookie";



fastcgi_hide_headerディレクティブは非垞に重芁です。 これがないず、セキュリティ䞊の重倧なリスクが発生したす。ナヌザヌはキャッシュ内のセッションCookieを通じお他のナヌザヌのセッションを取埗できたす。 確かに、nginxの最新バヌゞョンでは、この芁因を自動的に考慮するために䜕かが行われたした。これがどのように起こるか理解しおいたすか Vasya Pupkinはサむトにアクセスし、セッションずセッションCookieを受け取りたした。 その時点でキャッシュを空にするず、Vasina Cookieがキャッシュに曞き蟌たれたす。 その埌、別のナヌザヌが来お、キャッシュから応答を受け取り、その䞭にVasyaのCookieが入りたした。 それは圌のセッションも意味したす。



もちろん、次のように蚀うこずができたす。メむンペヌゞでsession_startを呌び出さないようにすれば、Cookieに問題はありたせん。 理論的にはこれは真実ですが、実際にはこの方法は非垞に䞍安定です。 倚くの堎合、セッションは「延期」されお開始され、セキュリティホヌルが発生するため、コヌドのどの郚分でもセッションぞのアクセスを必芁ずする関数を「誀っお」呌び出すだけで十分です。 たた、セキュリティは、特定の手法の過倱が原因でホヌルが発生する可胜性がある堎合、その手法は定矩䞊「挏れやすい」ず芋なされたす。 さらに、セッションCookieを陀く他のCookieがありたす。 たた、キャッシュに曞き蟌む必芁もありたせん。



fastcgi_ignore_headersタむプミス䞭にサむトを負荷から「暪に」させない


fastcgi_ignore_headers "Cache-Control" "Expires";



nginxサヌバヌは、PHPが生成するCache-Control、Expires、およびPragmaヘッダヌに泚意を払いたす。 ペヌゞをキャッシュする必芁がないたたは既に叀くなっおいるず蚀われた堎合、nginxはキャッシュファむルに曞き蟌みたせん。 この動䜜は、論理的に思えたすが、実際には倚くの困難を匕き起こしたす。 したがっお、ブロックしたす。fastcgi_ignore_headersのおかげで、芋出しに関係なく、ペヌゞのコンテンツはキャッシュファむルに保存されたす。



これらの困難は䜕ですか これらは再びセッションずsession_start関数に関連付けられたす。これは、PHPでデフォルトでヘッダヌ「Cache-Controlno-cache」ず「Pragmano-cache」を蚭定したす。 この問題には3぀の解決策がありたす。

ロヌタリヌキャッシング



静的なホヌムペヌゞはそれほど興味深いものではありたせん。 サむトに倚くの資料があり、メむンがそれらの䞀皮の「ショヌケヌス」ずしお機胜する堎合はどうすればよいですか このような「りィンドり」では、「ランダムな」玠材を衚瀺しお、さたざたなナヌザヌがさたざたなものを芋られるようにするず䟿利です1人のナヌザヌでも、ブラりザヌでペヌゞをリロヌドするこずで新しいコンテンツを受け取りたす。



゜リュヌションは、ロヌテヌションを䜿甚したキャッシュです。
  1. スクリプトを匷制的にランダムにメむンペヌゞに芁玠を返し、デヌタベヌスに必芁なク゚リをゆっくりではありたすが実行したす。
  2. 次に、1぀ではなく、たずえば10ペヌゞのバリ゚ヌションをキャッシュに保存したす。
  3. ナヌザヌがサむトにアクセスするず、これらのオプションの1぀が衚瀺されたす。 この堎合、キャッシュが空の堎合はスクリプトが起動され、空でない堎合はキャッシュから結果が返されたす。
  4. 別のナヌザヌが1日でサむトのすべおの資料を「芋る」こずができるように、キャッシュ゚ヌゞングタむムを小さく蚭定したすたずえば、1分。
その結果、スクリプトゞェネレヌタヌぞの最初の10個のリク゚ストが「正盎に」実行され、サヌバヌが「ロヌド」されたす。 しかし、それらはキャッシュに「萜ち着き」、1分以内にすでにすぐに発行されたす。 生産性の向䞊は、サむトぞの蚪問者が倚いほど倧きくなりたす。



回転キャッシュを実装するnginxの構成芁玠は次のずおりです。



 fastcgi_cache_path / var / cache / nginx levels = keys_zone = wholepage50m;
 perl_set $ rand 'sub {return int rand 10}';
 ...
サヌバヌ{
   ...
  堎所/ {
     ...
     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";

     ブラりザに毎回ペヌゞをリロヌドさせたすロヌテヌションのため。
     fastcgi_hide_header "Cache-Control";
     add_header Cache-Control "no-store、no-cache、must-revalidate、post-check = 0、pre-check = 0";
     fastcgi_hide_header "プラグマ";
     add_headerプラグマ「キャッシュなし」;

     垞に最新のLast-Modifiedを発行したす。
    期限切れ-1;  泚意!!! この期限切れの行が必芁です
     add_header Last-Modified $ sent_http_Expires;
   }
 }


前の䟋ず比范しお、堎所にさらに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 | ...";



ここで、ランダマむザヌ倉数をキャッシュキヌに混合しおいたす。その結果、同じURLに察しお10個の異なるキャッシュが必芁になりたした。キャッシュミス䞭に呌び出されるスクリプトはメむンペヌゞの芁玠をランダムな順序で提䟛するため、メむンペヌゞは10皮類あり、それぞれが1分間「存続」したすfastcgi_cache_validを参照。



add_headerブラりザのキャッシュを匷制的にオフにしたす


fastcgi_hide_header "Cache-Control";
add_header Cache-Control "no-store、no-cache、must-revalidate、post-check = 0、pre-check = 0";
fastcgi_hide_header "プラグマ";
add_headerプラグマ「キャッシュなし」;


䞊蚘では、nginxはPHPスクリプトによっお出力されるキャッシュヘッダヌの圱響を受けやすいず述べたした。 PHPスクリプトがヘッダヌ「Pragmano-cache」たたは「Cache-Controlno-store」を返した堎合さらに、たずえば「Cache-Controlno-save、no-issue、me-here-not-私はこれを蚀わなかった、これはこの垜子です、nginxは結果をキャッシュファむルに保存したせん。特にこの動䜜を抑制するために、fastcgi_ignore_headersを䜿甚したす䞊蚘を参照。



Pragmano-cacheずCache-Controlno-cacheの違いは䜕ですかプラグマがHTTP / 1.0のレガシヌであり、叀いブラりザヌずの互換性のために珟圚サポヌトされおいるからです。 HTTP / 1.1はCache-Controlを䜿甚したす。



ただし、ブラりザにはただキャッシュがありたす。たた、堎合によっおは、ブラりザがペヌゞを衚瀺するためにサヌバヌにリク゚ストを行おうずしないこずもありたす。代わりに、圌は自分のキャッシュからそれを取埗したす。なぜならロヌテヌションがあるため、この動䜜は䞍䟿です。ナヌザヌがペヌゞにアクセスするたびに、新しいデヌタを衚瀺する必芁があるためです。 実際、ただ1぀のオプションをキャッシュしたい堎合は、Cache-Controlヘッダヌを詊すこずができたす。



add_headerディレクティブは、キャッシュ犁止ヘッダヌをブラりザヌに枡すだけです。さお、このヘッダヌが誀っお増加するのを防ぐために、最初にHTTPレスポンスからPHPスクリプトが曞き蟌んだものおよびnginxキャッシュに曞き蟌たれたものを削陀したすfastcgi_hide_headerディレクティブ。結局、nginx configを䜜成するずき、PHPがそこに出力するこずを決定するかどうかはわかりたせんそしお、session_startが䜿甚される堎合、それは間違いなく決定したす。突然、圌は独自のCache-Controlヘッダヌを蚭定したすか次に、そのうちの2぀がありたす。PHP-shnyず、add_headerによっお远加されたす。



期限切れおよび最終倉曎保蚌ペヌゞの再読み蟌み


期限切れ-1; 泚意!!! この期限切れの行が必芁です
add_header最終倉曎$ sent_http_Expires;


別のトリックLast-Modifiedを珟圚の時刻に蚭定する必芁がありたす。残念ながら、nginxには珟圚の時刻を栌玍する倉数はありたせんが、expires -1ディレクティブを指定するず魔法のように衚瀺されたす。



これは珟圚文曞化されおいたせんが2009幎10月、nginxは、クラむアントに送信されるXXX応答ヘッダヌごずに$ sent_http_XXXの圢匏の倉数を䜜成したす。そのうちの1぀を䜿甚したす。



珟圚の時間にこの芋出しを蚭定するこずがなぜそれほど重芁なのですかすべおが非垞に簡単です。
  1. PHPがヘッダヌ「Last-Modifiedsome_date」を発行したずしたしょう。
  2. このヘッダヌはnginxキャッシュファむルに曞き蟌たれ確認できたすこの䟋では、ファむルは/ var / cache / nginxに栌玍されたす、クラむアントにブラりザヌに送信されたす。
  3. ブラりザはペヌゞずその倉曎日を蚘憶したす...
  4. 
 HTTP- - «If-Modified-Since: _».
  5. nginx? , Last-Modified If-Modified-Since. ( ), nginx «304 Not Modified» . : , .
実際、倧きな問題は、Last-ModifiedずCache-Control no-cacheの䞡方が存圚する堎合、ブラりザヌがどのように動䜜するかです。圌はIf-Modified-Sinceリク゚ストを行いたすかここでは、ブラりザが異なるず動䜜が異なるようです。実隓。



Last-Modifiedを手動で蚭定する理由がもう1぀ありたす。実際、session_startPHP関数はLast-Modifiedヘッダヌを匷制的に発行したすが、その䞭に最初に制埡を受け取ったPHPファむルぞの倉曎の時刻を瀺したす。したがっお、サむト䞊のすべおのリク゚ストが同じスクリプトフロントコントロヌラヌに送信される堎合、Last-Modifiedはこのスクリプトの倉曎にかかった時間ずほが垞に等しくなりたすが、これは完党に間違っおいたす。



キャッシュペヌゞの動的な「りィンドり」



そしお最埌に、キャッシュの芳点から有甚なテクニックの1぀を玹介したす。サむトのメむンたたは他のペヌゞをキャッシュしたいが、動的でなければならない1぀の小さなブロックが干枉する堎合は、SSIを操䜜するためにモゞュヌルを䜿甚したす。



ペヌゞの動的な郚分に、次のHTMLコメントを挿入したす。



<-include virtual = "/ get_user_info /"->


nginxキャッシュに関しおは、このコメントはプレヌンテキストです。コメントずしおキャッシュファむルに保存されたす。ただし、埌でキャッシュを読み取るずきに、SSI nginxモゞュヌルが機胜し、動的URLを参照したす。もちろん、アドレス/ get_user_info /には、このブロックの内容を返すPHPハンドラヌが必芁です。この方法に぀いおは、Habrのこの蚘事で詳しく説明しおいたす。



もちろん、このペヌゞたたはサヌバヌ党䜓でSSIを有効にするこずを忘れないでください。



ssi on;


SSI includeディレクティブには、非垞に重芁な別のプロパティがありたす。そのようなディレクティブがペヌゞ䞊で芋぀かるず、それらのすべおが䞊行モヌドで同時に凊理され始めたす。したがっお、ペヌゞに4぀のブロックがあり、それぞれが200ミリ秒をロヌドする堎合、合蚈ペヌゞは800ではなく200ミリ秒でナヌザヌに受信されたす。



この蚘事の゜ヌスコヌドはここで読むこずができたすhttp : //dklab.ru/chicken/nablas /56.html



All Articles