1. ワニスの紹介 Varnish は、高性能なオープンソースのリバースプロキシサーバーおよび HTTP キャッシュサーバーです。その機能は Squid サーバーの機能に似ており、HTTP キャッシュに使用できます。任意の Web フロントエンドに Varnish をインストールし、コンテンツをキャッシュするように構成できます。従来の Squid と比較して、Varnish には、パフォーマンスの向上、速度の高速化、管理の容易化など、多くの利点があります。一部の企業では、同じサーバーコストでより優れたキャッシュ効果を実現するために、古いバージョンの Squid の代替として、すでに実稼働環境で Varnish を使用しています。Varnish は、CDN キャッシュ サーバーのオプション サービスの 1 つでもあります。 Varnish の主な機能は次のとおりです。 キャッシュの場所: メモリまたはディスクのいずれかを使用できます。ディスクを使用する場合、RAID1 には SSD が推奨されます。 ログの保存: ログもメモリに保存されます。ストレージ戦略: 固定サイズ、循環使用。 仮想メモリの使用をサポートします。 キャッシュの時間属性制御という正確な時間管理メカニズムがあります。 状態エンジン アーキテクチャ: 異なるキャッシュ データとプロキシ データの処理は、異なるエンジンで完了します。特定の構成言語を使用してさまざまな制御ステートメントを設計し、さまざまな場所でデータをキャッシュするさまざまな方法を決定したり、特定の場所で特定のルールに従って渡されるメッセージを処理したりできます。 キャッシュ管理: キャッシュ データをバイナリ ヒープ形式で管理し、タイムリーなデータ クリーンアップを実現します。 Squidと比較すると、Varnishはリバースプロキシキャッシュサーバーであり、どちらもオープンソースです。Squidはハードディスクからキャッシュされたデータを読み取りますが、Varnishはデータをメモリに保存し、メモリを直接読み取るため、メモリとディスク間の頻繁なファイルスワップが回避されるため、Varnishは非常に安定しており、アクセス速度が速いです。そのため、Varnishは比較的効率的です。VarnishはSquidよりもTCP接続を高速に解放するため、より多くの同時接続をサポートできます。また、Varnishは正規表現を使用して、管理ポートを介してキャッシュの一部を一括でクリアすることもできますが、これはSquidではできません。SquidはシングルコアCPUを使用する単一プロセスですが、Varnishは処理のためにフォークの形で複数のプロセスを開くため、すべてのコアを合理的に使用して対応するリクエストを処理できます。 上記では Varnish の多くの利点について述べましたが、Varnish は完璧ではありません。主な欠点は次のとおりです。 1. Varnishプロセスがクラッシュまたは再起動すると、キャッシュされたデータはメモリから完全に解放され、すべてのリクエストは バックエンド サーバーに送信すると、同時実行性が高い状況ではバックエンド サーバーに大きな負荷がかかります。 2. Varnish を使用する場合、単一の URL リクエストが HA/F5 などのロードバランサーを通過すると、各リクエストが異なる Varnish サーバーに送られ、リクエストがバックエンドに浸透します。また、同じリクエストが複数のサーバーにキャッシュされるため、Varnish のキャッシュリソースが浪費され、パフォーマンスが低下します。 ワニスの欠点に対する解決策: デメリット 1 について: トラフィックが大きい場合は、Varnish のメモリ キャッシュ モードの使用を開始することをお勧めします。それには、複数の Squid/nginx サーバーが必要です。これは主に、以前の Varnish サービスまたはサーバーが再起動されたときに、大量のリクエストが Varnish に侵入するのを防ぐためです。これにより、Squid/nginx が第 2 層の CACHE として動作することができ、再起動時にメモリ内の Varnish キャッシュが解放されるという問題も補えます。 2 番目の欠点: ロード バランサーで URL ハッシュを実行して、単一の URL 要求を Varnish サーバーに固定することができます。 2. Varnishの仕組み Varnish のマスタープロセスは、作業の開始を担当します。マスタープロセスは、構成ファイルを読み取り、指定されたスペースサイズに応じてストレージスペースを作成し (たとえば、管理者が 2G のメモリを割り当てた場合)、子プロセスを作成して管理します。 その後、子プロセスが後続のタスクを処理します。子プロセスは、HTTP リクエストの受け入れ、キャッシュ オブジェクト用のストレージ領域の割り当て、期限切れのキャッシュ オブジェクトのクリア、領域の解放、デフラグなどのさまざまなタスクを実行するためにいくつかのスレッドを割り当てます。 http リクエストの処理プロセスは次のとおりです。 1. HTTP リクエストの受信専用のスレッドがあり、リクエスト ポートをリッスンし続けます。リクエストが来ると、ワーカー スレッドを呼び出してリクエストを処理します。ワーカー スレッドは、HTTP リクエストの URI を分析し、リクエストが何を求めているかを把握してから、キャッシュ内のオブジェクトを探します。キャッシュ オブジェクトが見つかった場合は、キャッシュ オブジェクトが直接ユーザーに返されます。見つからない場合は、リクエストはバックエンド サーバーに転送されて処理され、結果を待機します。ワーカー スレッドは、バックエンドから結果コンテンツを取得した後、まずそのコンテンツをキャッシュ オブジェクトとしてキャッシュ スペースに保存し (次にオブジェクトが要求されたときにすばやく応答できるように準備するため)、次にそのコンテンツをユーザーに返します。 キャッシュ割り当てプロセスは次のとおりです。 オブジェクトをキャッシュする必要がある場合、オブジェクトのサイズに基づいて、空きキャッシュ領域で最適なサイズの空きブロックが検索されます。見つかったら、オブジェクトはそこに配置されます。オブジェクトが空きブロックを埋め尽くさない場合は、残りのスペースが新しい空きブロックとして使用されます。空きキャッシュ領域に空きがない場合は、キャッシュの一部を削除してスペースを確保する必要があります。削除は、最近最も使用されていないものの原則に基づいて行われます。 キャッシュを解放するプロセスは次のとおりです。 キャッシュの解放を担当するスレッドがあります。このスレッドは、キャッシュ内のすべてのオブジェクトのライフサイクルを定期的にチェックします。指定された期間内にオブジェクトにアクセスされていない場合は、そのオブジェクトを削除し、そのオブジェクトが占有しているキャッシュ領域を解放します。領域を解放した後、隣接するメモリ領域が空いているかどうかを確認します。空いている場合は、より大きな空きブロックに統合され、領域の断片化が実現されます。 Varnish のその他の機能については、Varnish の公式 Web サイトをご覧ください。 3. Varnish Cache Serverをデプロイする 環境準備: IP アドレスがそれぞれ 192.168.20.5、20.4、20.3 である 3 台の CentOS 7.5 サーバー。 このうち、IP192.168.20.5 は Varnish キャッシュ サーバーで、他の 2 つはバックエンド Web サーバーです。それぞれに異なる Web ページ ファイルを用意し (ここでは Web ページの内容をその IP に変更します)、キャッシュ効果を確認します。 私が提供した Varnish ソース パッケージをダウンロードし、Varnish サーバーにアップロードします。 1. Varnish のデプロイとインストールを開始します。 [root@varnish ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo : : : : : : : : : : : : : : : # # これは Varnish の VCL ファイルの例です。 # # デフォルトでは何もせず、制御を委任します # 組み込みVCL。組み込みVCLは、明示的な # return ステートメント。 # # https://www.varnish-cache.org/docs/ のユーザーガイドの VCL の章を参照してください。 # その他の例については、http://varnish-cache.org/trac/wiki/VCLExamples を参照してください。 # このVCLがVCLコンパイラに適合していることをVCLコンパイラに伝えるマーカー # 新しい 4.0 形式。 4.0; 輸入ディレクター; std をインポートします。 # デフォルトのバックエンド定義。コンテンツ サーバーを指すように設定します。 プローブ backend_healthcheck { .url="/"; #バックエンドサーバーのルートパスにアクセスします。interval = 5s; #リクエスト時間間隔。timeout = 1s; #リクエストタイムアウト。window = 5; #ポーリング回数を5回指定します。threshold = 3; #失敗が3回ある場合は、バックエンドサーバーがダウンしていることを意味します} backend web1 { #バックエンド サーバーを定義します。host = "192.168.20.4"; #リダイレクトするホスト (つまり、バックエンド ホスト) の IP またはドメイン名。port = "80"; #バックエンド サーバーのポート番号を指定します。probe = backend_healthcheck; #ヘルス チェックは backend_healthcheck で定義されたコンテンツを呼び出します} バックエンドWeb2 { .host = "192.168.20.3"; .port = "80"; .probe = backend_healthcheck; } acl purgers { #define アクセス制御リスト "127.0.0.1"; "ローカルホスト"; 「192.168.20.0/24」; !"192.168.20.4"; } sub vcl_init { #vcl_initを呼び出してサブルーチンを初期化し、バックエンドホストグループ(ディレクター)を作成します new web_cluster = directors.round_robin(); #新しいキーワードを使用してディレクター オブジェクトを作成し、round_robin アルゴリズムを使用します web_cluster.add_backend(web1); #バックエンド サーバー ノードを追加します web_cluster.add_backend(web2); } サブvcl_recv { set req.backend_hint = web_cluster.backend(); #リクエストのバックエンドノードを指定します web_cluster で定義されたバックエンドノード if (req.method == "PURGE") { #クライアントのリクエストヘッダーが PURGE かどうかを判断します if (!client.ip ~ purgers) { # yes の場合は、クライアントの IP アドレスが ACL アクセス制御リストに含まれているかどうかを確認します。 return (synth(405, "Not Allowed.")); #そうでない場合は、クライアントに 405 ステータス コードを返し、定義されたページを返します。 } return (purge); #ACLで定義されている場合はpurgeで処理されます。 } if (req.method != "GET" && 要求メソッド != "HEAD" && 要求メソッド != "PUT" && 要求メソッド != "POST" && 要求メソッド != "TRACE" && req.method != "オプション" && req.method != "PATCH" && req.method != "DELETE") { #クライアントのリクエストタイプを判断する return (pipe); } 要求メソッドが "GET" で、要求メソッドが "HEAD" の場合 { return (pass); #GETでもHEADでもない場合は渡します。 } 必要であれば、req.url を "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)" に設定します。 return (pass); #クライアントが.phpで終わるファイルにアクセスすると、処理のためにpassに渡します。 } http.Authorization が必要な場合 return (pass); #クライアントが要求したページタイプが認証を必要とする場合は、それをプロセスに渡します} if (req.http.Accept-Encoding) { if (req.url ~ "\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$") { unset req.http.Accept-Encoding; #クライアントが受信した圧縮タイプをキャンセルします} elseif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; #gzip タイプがある場合は、gzip タイプをマークします。 } elseif (req.http.Accept-Encoding ~ "deflate") { req.http.Accept-Encoding = "deflate" を設定します。 } それ以外 { unset req.http.Accept-Encoding; #その他の未定義のページも、クライアントが受信した圧縮タイプをキャンセルします。 } } if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") { unset req.http.cookie; #クライアントのクッキー値をキャンセルします。 return (hash); #リクエストをハッシュサブルーチンに転送し、ローカルキャッシュをチェックします。 } if (req.restarts == 0) { #クライアントからの最初のリクエストかどうかを判断します。 if (req.http.X-Forwarded-For) { #最初のリクエストの場合は、クライアントの IP アドレスを設定します。 req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip を設定します。 } それ以外 { req.http.X-Forwarded-For = client.ip を設定します。 } } 戻り値(ハッシュ); } サブvcl_hash{ hash_data(req.url); #クライアントが要求したページを表示し、ハッシュ化を実行します (http.hostが必要な場合){ hash_data(req.http.host); #クライアントのホストを設定する} else { hash_data(server.ip); #サーバーのIPを設定する } 返す(検索); } サブvcl_hit { if (req.method == "PURGE") { #HIT であり、クライアント要求タイプが PURGE の場合、ステータス コード 200 を返し、対応するページを返します。 return (synth(200, "パージされました。")); } 返す(配達する); } サブvcl_miss { (req.method == "PURGE"の場合){ return (synth(404, "Purged.")); # ミスの場合は 404 を返します } 返す(フェッチ); } サブvcl_deliver { (obj.hits > 0)の場合{ set resp.http.CXK = "HIT-from-varnish"; #http ヘッダー X-Cache = hit を設定します set resp.http.X-Cache-Hits = obj.hits; #コマンドの数を返す} else { resp.http.X-Cache = "MISS" を設定します。 } unset resp.http.X-Powered-By; #Web バージョンの表示をキャンセルunset resp.http.Server; #Varnish サービスの表示をキャンセルunset resp.http.X-Drupal-Cache; #キャッシュされたフレームワークの表示をキャンセルunset resp.http.Via; #ファイル コンテンツ ソースの表示をキャンセルunset resp.http.Link; #HTML ハイパーリンク アドレスの表示をキャンセルunset resp.http.X-Varnish; #Varnish ID の表示をキャンセル set resp.http.xx_restarts_count = req.restarts; #クライアント要求の数を設定します set resp.http.xx_Age = resp.http.Age; #キャッシュされたファイルの長さを表示します #set resp.http.hit_count = obj.hits; #キャッシュヒットの数を表示します #unset resp.http.Age; 返す(配達する); } サブvcl_pass { return (fetch); #バックエンドサーバーから返されたデータをローカルにキャッシュします} サブvcl_backend_response { beresp.grace = 5m と設定します。# 追加の猶予時間をキャッシュしますif (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) { beresp.uncacheable = true と設定します。#バックエンドサーバーがステータスコード 449 などで応答した場合はキャッシュしません} if (bereq.url ~ "\.(php|jsp)(\?|$)") { beresp.uncacheable = true と設定します。#PHP ページの場合はキャッシュされません} else { if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico)($|\?)") { set beresp.ttl = 15m; #上記で終了したら15分間キャッシュします unset beresp.http.Set-Cookie; } elseif (bereq.url ~ "\.(gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") { set beresp.ttl = 30m; #30分間キャッシュ unset beresp.http.Set-Cookie; } それ以外 { beresp.ttl を 10m に設定する; #有効期間 10 分 beresp.http.Set-Cookie を未設定にする; } } 返す(配達する); } サブvcl_purge{ 戻り値 (synth(200,"成功")); } サブvcl_backend_error { beresp.status == 500 の場合 || beresp.ステータス == 501 || beresp.ステータス == 502 || beresp.ステータス == 503 || beresp.ステータス == 504) { return (retry); #ステータスコードが上記のいずれかの場合、再リクエスト} } サブvcl_fini { 戻り値 (OK); } #編集後は保存して終了します。 [root@varnish varnish]# varnishd -f /usr/local/var/varnish/example.vcl -s malloc,200M -a 0.0.0.0:80 # Varnish サービスを開始し、すべてのローカル IP アドレスのポート 80 をリッスンします。-f は vcl ファイルを指定し、-s はキャッシュを保存する容量を指定します。[root@varnish ~]# varnishlog # Varnish を起動したら、このコマンドを実行してログを表示できます。 いくつかの機能をテストするためのクライアント アクセス (Google Chrome でアクセスする前に「F12」を押します): 更新するには「F5」を押してください: 設定ファイルで指定されたヘッダー情報にアクセスし、ステータス コードは 304 になります。 ACL クリア キャッシュ構成を確認します。 ホスト 192.168.20.4 のキャッシュをクリアします (Varnish はこの IP がキャッシュをクリアできないように設定されています)。 [root@localhost ~]# curl -X "PURGE" 192.168.20.5 # Varnish キャッシュをクリア 次のエラー メッセージが表示されます。 Varnish によって許可された IP (ホスト 192.168.20.3) のキャッシュをクリアすると、次の成功メッセージが表示されます。 追加: 上記のコメントされていない完全な構成ファイルは次のとおりです。 4.0; 輸入ディレクター; std をインポートします。 プローブ backend_healthcheck { .url="/"; .interval = 5秒; .タイムアウト = 1秒; .window = 5; .しきい値 = 3; } バックエンド web1 { .host = "192.168.20.4"; .port = "80"; .probe = backend_healthcheck; } バックエンドWeb2 { .host = "192.168.20.3"; .port = "80"; .probe = backend_healthcheck; } ACL パージャー { 「127.0.0.1」; "ローカルホスト"; 「192.168.20.0/24」; !"192.168.20.4"; } サブvcl_init { 新しい web_cluster = directors.round_robin(); web_cluster.add_backend(web1); web_cluster.add_backend(web2); } サブvcl_recv { req.backend_hint = web_cluster.backend() を設定します。 (req.method == "PURGE"の場合){ if (!client.ip ~ purgers) { return (synth(405, "許可されていません。")); } 戻す(パージ) } if (req.method != "GET" && 要求メソッド != "HEAD" && 要求メソッド != "PUT" && 要求メソッド != "POST" && 要求メソッド != "TRACE" && req.method != "オプション" && req.method != "PATCH" && req.method != "DELETE") { 戻り値(パイプ) } 要求メソッドが "GET" で、要求メソッドが "HEAD" の場合 { 返す(渡す) } 必要であれば、req.url を "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)" に設定します。 返す(渡す) } http.Authorization が必要な場合 返す(渡す) } if (req.http.Accept-Encoding) { if (req.url ~ "\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$") { req.http.Accept-Encoding を設定解除します。 } elseif (req.http.Accept-Encoding ~ "gzip") { req.http.Accept-Encoding = "gzip" を設定します。 } elseif (req.http.Accept-Encoding ~ "deflate") { req.http.Accept-Encoding = "deflate" を設定します。 } それ以外 { req.http.Accept-Encoding を設定解除します。 } } if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") { req.http.cookie を設定解除します。 戻り値(ハッシュ); } (req.restarts == 0)の場合{ (http.X-Forwarded-For が必要)の場合 { req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip を設定します。 } それ以外 { req.http.X-Forwarded-For = client.ip を設定します。 } } 戻り値(ハッシュ); } サブvcl_hash{ ハッシュデータ(req.url); (http.hostが必要な場合){ ハッシュデータ(req.http.host); } それ以外 { hash_data(サーバのIP); } 返す(検索); } サブvcl_hit { (req.method == "PURGE"の場合){ return (synth(200, "パージされました。")); } 返す(配達する); } サブvcl_miss { (req.method == "PURGE"の場合){ return (synth(404, "パージされました。")); } 返す(フェッチ); } サブvcl_deliver { (obj.hits > 0)の場合{ resp.http.CXK = "HIT-from-varnish" を設定します。 resp.http.X-Cache-Hits = obj.hits を設定します。 } それ以外 { resp.http.X-Cache = "MISS" を設定します。 } resp.http.X-Powered-By の設定を解除します。 resp.http.Server の設定を解除します。 resp.http.X-Drupal-Cache の設定を解除します。 resp.http.Via の設定を解除します。 resp.http.Link を設定解除します。 resp.http.X-Varnish の設定を解除します。 resp.http.xx_restarts_count = req.restarts を設定します。 resp.http.xx_Age を resp.http.Age に設定します。 #resp.http.hit_count を obj.hits に設定します。 #resp.http.Age を設定解除します。 返す(配達する); } サブvcl_pass { 返す(フェッチ); } サブvcl_backend_response { beresp.grace = 5m を設定します。 beresp.status == 499 || beresp.status == 404 || beresp.status == 502 の場合 { beresp.uncacheable を true に設定します。 } if (bereq.url ~ "\.(php|jsp)(\?|$)") { beresp.uncacheable を true に設定します。 } それ以外 { if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico)($|\?)") { beresp.ttl = 15m を設定します。 beresp.http.Set-Cookie を設定解除します。 } elseif (bereq.url ~ "\.(gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") { beresp.ttl = 30m を設定します。 beresp.http.Set-Cookie を設定解除します。 } それ以外 { beresp.ttl = 10m を設定します。 beresp.http.Set-Cookie を設定解除します。 } } 返す(配達する); } サブvcl_purge{ 戻り値 (synth(200,"成功")); } サブvcl_backend_error { beresp.status == 500 の場合 || beresp.ステータス == 501 || beresp.ステータス == 502 || beresp.ステータス == 503 || beresp.ステータス == 504) { 戻る(再試行); } } サブvcl_fini { 戻り値 (OK); } 実際、Varnish のキャッシュ機能を実装したい場合は、次の基本定義を通じて実装できます (example.vcl ファイルの次の内容で十分です)。 4.0; 輸入ディレクター; プローブ backend_healthcheck { .url = "/"; .タイムアウト = 1秒; .interval = 5秒; .window = 5; .しきい値 = 3; } バックエンド web1 { .host = "192.168.20.3"; .port = "80"; .probe = backend_healthcheck; } バックエンドWeb2 { .host = "192.168.20.4"; .port = "80"; .probe = backend_healthcheck; } サブvcl_init { 新しい web_cluster = directors.round_robin(); web_cluster.add_backend(web1); web_cluster.add_backend(web2); } サブvcl_recv { req.backend_hint = web_cluster.backend() を設定します。 } 要約する 以上が CentOS 7.5 に導入された Varnish キャッシュ サーバー機能の紹介です。お役に立てれば幸いです。ご質問がございましたら、メッセージを残していただければ、すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。 以下もご興味があるかもしれません:
|
<<: jsを使用して中国語からピンインへの変換の完全な手順を実行します
>>: MySQLデータベースが大きすぎる場合にバックアップと復元を行う方法
需要背景統計インターフェースでは、フロントエンドは 2 つの配列を返す必要があります。1 つは 0 ...
この記事の例では、カルーセルのフレームレート再生を実現するためのVueの具体的なコードを参考までに共...
Mongodb には db.serverStatus() コマンドがあり、これを使用して Mongo...
この記事では、例を使用して、MySQL ストアド プロシージャで複数の値を返す方法について説明します...
私はしばらくの間チャートをいじっていましたが、好奇心から、CSS を使用してチャートを作成するより良...
昨日は写真をアップロードしてリンクを返す機能を実装していました。プロジェクトが Tomcat に再デ...
最近ファイルシステムを作ったのですが、フィールドが多すぎることに気づきましたページングを使用した複数...
Nestjs 例外フィルターといえば、非常に強力な .Net のグローバル フィルターについて触れな...
オーディオおよびビデオ ファイルを保存するためのディスク寿命を延ばすには、ディスクをフォーマットする...
この記事では、参考までに、簡単なログイン機能を実装するためのvue+tp5の具体的なコードを紹介しま...
質問:最近、プロジェクトの統計を行っていたときに、テーブルを上下にスクロールしたときにテーブルの先頭...
序文MySQL クラスターを構築する場合、当然のことながら、データの一貫性を確保するために、データベ...
目次序文環境インストールMySQLコンテナを作成して起動する落とし穴を避けるための注意MySQLコン...
CSS でレスポンシブ レイアウトを実装するレスポンシブレイアウトは非常にハイエンドで難しいように思...
まずは効果を見てみましょう:この効果は非常に華やかに見えますが、原理は複雑ではありません。1 枚の花...