序文 Tomcat 内のすべてのリクエストは Servlet によって処理され、静的リソースも例外ではありません。デフォルトの web.xml では、キャッシュとブレークポイントの再開をサポートする静的リソースを処理するように DefaultServlet が設定されています。 DefaultServlet の基本的な処理は次のとおりです。
次に、リソース キャッシュの設計と実装、および If ヘッダー フィールドの処理を主に分析します。 1. リソースキャッシュの設計 ディスクへのアクセス速度はメモリへのアクセス速度よりもはるかに遅いため、一部の静的リソースを適切にキャッシュすると、システムの応答が速くなります。 Tomcat がバージョン 6.0.53 で静的リソースの処理を実装したとき、いくつかの JNDI API が使用されました (ただし、使用時に JNDI とはほとんど関係がないと感じられました)。関連するクラス ダイアグラムとコア メソッドおよびプロパティは次のとおりです。 キャッシュ関連クラス:
リソース ディレクトリ関連のクラスは次のとおりです。
デフォルトでは、キャッシュの最大サイズは 10 MB、キャッシュされた単一のリソースの最大サイズは 512 KB、キャッシュ TTL は 5 秒です。 通常、Mapper が静的リソースを処理する Wrapper にマップされると、リソースの読み込みが発生します。基本的なメソッド呼び出しは次のとおりです。 Mapper.map(メッセージバイト、メッセージバイト、マッピングデータ) └─Mapper.internalMap(CharChunk、CharChunk、MappingData) └─Mapper.internalMapWrapper(Mapper$Context、CharChunk、MappingData) └─ProxyDirContext.lookup(文字列) └─ProxyDirContext.cacheLookup(文字列) └─ResourceCache.lookup(文字列) └─ResourceCache.find(CacheEntry[], 文字列) キャッシュ リソースは、順番に内部配列に挿入されます。find メソッドは、リソース名でキャッシュ内でバイナリ検索を実行します。リソース名はリクエスト パスです。キャッシュ ヒットとキャッシュ ミスの 2 つの状況があります。 キャッシュが見つからない場合、cacheLookup メソッドで新しい CacheEntry オブジェクトが作成され、cacheLoad メソッドが呼び出されて、それが ResourceCache のキャッシュ配列に追加されます。追加する前に、キャッシュ エントリに対して次の操作が実行されます。
キャッシュヒットはキャッシュエントリを検証します:
上記はリソースキャッシュの簡単な処理プロセスです。 2. Ifヘッダーフィールドの処理 クライアントは要求されたリソースを受信してキャッシュします。リソースを再度要求すると、サーバーは特定の要求ヘッダー フィールドに基づいてリソースが変更されたかどうかを確認します。変更がない場合は、304 Not Modified 応答のみが返されます。変更がない場合は、リソースのコンテンツが返されるため、帯域幅が節約されます。 リソース検証に使用されるヘッダー フィールドは、Last-Modified+If-Modified-Since と ETag+If-None-Match の 2 つです。 Last-Modified+If-Modified-Since、単位は秒です。これは理解しやすいです。サーバー リソースの最終変更時刻が If-Modified-Since の値より小さい場合、リソースが変更されていないことを意味します。 If-Modified-Since に対応するのは、アサーションに似た If-Unmodified-Since です。これより小さいタイムスタンプを持つリソースのみが返されます。タイムスタンプがこれより大きいか等しい場合は、412 Precondition Failed エラーが返されます。 タイムスタンプ検証を使用すると、いくつかの欠点があります。
そのため、HTTP では ETag が導入されました。 ETag (エンティティ タグ) はリソースの一意の識別子であり、リソースに対してサーバーによって生成されたトークンと見なすことができ、リソースが変更されたかどうかを確認するために使用されます。 HTTP では、ETag を二重引用符で囲む必要があると規定されているだけで、その内容や実装方法については規定されていません。Tomcat の ETag 生成ロジックは ETag+If-None-Match。If-None-Match の値は、コンマで区切られた 1 つ以上の ETag で構成されます。サーバー リソースの ETag がいずれにも一致しない場合は、要求されたリソースが変更されたことを意味します。それ以外の場合は、変更はありません。また、アスタリスク (*) という特別な値もあります。これは、リソースをアップロードするとき (通常は PUT メソッド) にのみ使用され、アップロードされたかどうかを確認します。 さらに、If-None-Match は If-Modified-Since よりも優先度が高く、つまり If-None-Match が存在する場合、最終変更時刻はチェックされません。 If-None-Match の反対は If-Match で、これもアサーションに似ています。リソースの ETag が一致する場合にのみ変更されていないと見なされます。通常は、ブレークポイントの再開に使用されます。 この部分を実装するための Tomcat のコア コードは次のとおりです。 // リソースが変更されたとみなされる場合にのみtrueを返す protected boolean checkIfHeaders(HttpServletRequest request, HttpServletResponse レスポンス、ResourceAttributes リソース属性) IOException をスローします { checkIfMatch(リクエスト、レスポンス、リソース属性) を返します && checkIfModifiedSince(リクエスト、レスポンス、リソース属性) && checkIfNoneMatch(リクエスト、レスポンス、リソース属性) && checkIfUnmodifiedSince(リクエスト、レスポンス、リソース属性); } 2.1 ワンタイムリクエストプロセス /main.css 静的リソースのリクエストを例にとると、最初のリクエスト応答ヘッダー情報は次のようになります。 HTTP/1.1 200 OK サーバー: Apache-Coyote/1.1 受け入れ範囲: バイト ETag: W/"72259-1557127244000" 最終更新日: 2019年5月6日(月) 07:20:44 GMT コンテンツタイプ: text/css コンテンツの長さ: 72259 日付: 2019年5月6日月曜日 07:20:57 GMT 2 番目のリクエストを行うときは、まずリクエスト ヘッダー フィールドの重要な情報を確認します。 キャッシュ制御:max-age=0 接続:キープアライブ ホスト:localhost:8080 変更日時: 2019 年 5 月 6 日 (月) 07:20:44 GMT 一致しない場合:W/"72259-1557127244000" リクエストを受信すると、サーバーは ETag を比較します。一致した場合、リソースは変更されていないことを意味します。応答は次のようになります。 HTTP/1.1 304 変更されていません サーバー: Apache-Coyote/1.1 ETag: W/"72259-1557127244000" 日付: 2019年5月6日月曜日 07:21:46 GMT 注意: 再生する場合はテキストタイプを使用してください。Chrome ブラウザを使用する場合は、キャッシュを有効にすることを忘れないでください。 2.2 受け入れ範囲 上記の応答では、サーバーは Accept-Ranges: bytes ヘッダーを設定します。これは文字通り、リソースのバイトの一部を要求できることを意味します。クライアントがこのヘッダーを見つけると、転送を再開しようとすることができます。 解析処理は HTTP 仕様の実装です。ここでは詳細に分析しません。仕様の詳細については、RFC7233#section-2.3 を参照してください。 3. SendFile処理 SendFile がサポートされているかどうかを確認します。この操作は NIO モード、つまりゼロ コピーでサポートされます。この操作により、アプリケーション メモリへのコピーが 1 つ削減され、カーネルからチャネルに直接データが書き込まれます。 Tomcat は 48KB を超えるファイルを送信するためにこのメソッドを使用しようとします。 4. まとめ Tomcat の静的リソース処理の実装は比較的完成していますが、Nginx などの Web サーバーでは静的リソースを直接処理できるのに対し、Tomcat では追加のマッピングを行う必要があるため、それに比べるとまだ若干劣っています。一般的に、Tomcat が動的リクエストの処理に集中できるように、動的と静的の分離が実行されます。 要約する 以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。 以下もご興味があるかもしれません:
|
<<: Linux での MySQL 5.1 および 5.7 のインストール チュートリアル
>>: Reactの新バージョンのライフサイクルフック機能と使用方法の詳細な説明
目次1. オペレーター要約する1. オペレーター演算子は、代入、比較、算術演算などの機能を実装するた...
前回の記事では、MySQL 5.7.19 無償インストール版 (64 ビット) の設定方法についての...
圧縮アップロード画像、スクラッチカード、ポスター作成、チャートプラグインなど、フロントエンド開発にお...
複雑なテーブル構造では、一部のセルが垂直方向に複数のセルにまたがるため、列間属性 COLSPAN を...
この記事では、Linux ファイル管理コマンドについて例を挙げて説明します。ご参考までに、詳細は以下...
方法1: cmdコマンドを使用するまず、DOS ウィンドウを開き、スタート、実行、cmd と入力しま...
目次導入説明書実際の経験長所と短所総括する導入mysqlpump は mysqldump の派生です...
ナビゲーション バー、固定トップ ナビゲーション バー、およびセカンダリ メニューの実装効果図の実装...
この記事では、Docker コンテナとフロントエンド プロセスの関係と、コンテナを永続的に実行できる...
JavaScript ではオブジェクトを走査する順序は固定されていないと聞いたことがある人もいるかも...
Union は、重複行を除外し、デフォルトのソートを実行する、データに対する結合操作です。Union...
1. 分散ストレージシステムの概要情報技術の継続的な発展により、利便性がもたらされる一方で、データ量...
VMware バージョン: VMware-workstation-full-16 VMware バー...
1. ボタンで使用される値は、「OK」、「削除」など、ボタンに表示されるテキストを指します。 2. ...
準備Windows Server 2008 R2 Enterprise (2.40GH、8GB、64...