Tomcatをバージョン7.0.52から8.0.14にアップグレードしました。
私はこれをたくさんの静的な画像ファイルに使っています:
org.Apache.catalina.webresources.Cache.getResource期限切れのキャッシュを排除した後に利用可能な空き容量が不足していたため、[/ base/1325/WA6144-150x112.jpg]のリソースをキャッシュに追加できませんエントリ - キャッシュの最大サイズを増やすことを検討してください
特定のリソース設定は指定していませんが、7.0.52ではこれを取得できませんでした。
私はこれが起動時に起こっていることの言及を見つけられたと思われるバグ報告の中でおそらく修正されました。私にとっては、これは起動時ではなく、リソースが要求されたときに常に起きています。
この問題を抱えている人はいますか?
少なくとも単にキャッシュを無効にしようとしていますが、キャッシュを使用しないように指定する方法の例が見つかりません。属性はTomcatバージョン8のコンテキストから削除されました。リソースを追加しようとしましたが、設定権を取得できません。
<Resource name="file"
cachingAllowed="false"
className="org.Apache.catalina.webresources.FileResourceSet"
/>
ありがとう。
$CATALINA_BASE/conf/context.xml
では、</Context>
の前に下記のブロックを追加してください
<Resources cachingAllowed="true" cacheMaxSize="100000" />
詳細については、 http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html を参照してください。
Tomcat 7から8にアップグレードするときにも同じ問題がありました。キャッシュに関する大量のログ警告が継続的に発生します。
これを$CATALINA_BASE/conf/context.xml
の- Context
xml要素内に追加します。
<!-- The default value is 10240 kbytes, even when not added to context.xml.
So increase it high enough, until the problem disappears, for example set it to
a value 5 times as high: 51200. -->
<Resources cacheMaxSize="51200" />
したがって、デフォルトは10240
(10メガバイト)なので、これよりも大きいサイズを設定します。警告が消える最適な設定を調整するよりも。警告は、交通量の多い状況で戻ってくる場合があることに注意してください。
この問題は、キャッシュエントリがそれらのエントリのTTLより小さいため、Tomcatがターゲットキャッシュサイズに到達できないために発生します。そのため、Tomcatは、新鮮すぎるため期限切れになるほどのキャッシュエントリを持っていませんでした。そのため、十分なキャッシュを解放できず、警告を出力しました。
Tomcat 7はこの状況では単に警告を出力しなかったため、Tomcat 7では問題は発生しませんでした。 (通知されずに不適切なキャッシュ設定を使用することになります。)
この問題は、キャッシュのサイズとTTLと比較して、比較的短時間でリソース(通常は静的)に対して比較的大量のHTTPリクエストを受信した場合に発生します。キャッシュが最大サイズ(デフォルトでは10MB)に達し、そのサイズの95%以上が新しいキャッシュエントリ(キャッシュは5秒未満)に達すると、Tomcatが試行する各webResourceの警告メッセージが表示されますキャッシュにロードします。
実行中のサーバーを再起動せずにcacheMaxSizeを調整する必要がある場合は、JMXを使用します。
最も簡単な修正方法は、キャッシュを完全に無効にすることです:<Resources cachingAllowed="false" />
、しかしそれは最適ではないため、先ほど説明したようにcacheMaxSizeを増やします。
WebSource は、Webアプリケーションのファイルまたはディレクトリです。パフォーマンス上の理由から、TomcatはWebSourceをキャッシュできます。 静的リソースキャッシュの最大 (すべてのリソースの合計)は、デフォルトでは10240 kバイト(10 mバイト)です。 webResourceは、webResourceが要求されたとき(たとえば、静的イメージを読み込むとき)にキャッシュに読み込まれ、キャッシュエントリと呼ばれます。すべてのキャッシュエントリには TTL (有効期間)があります。これは、キャッシュエントリがキャッシュ内に留まることができる時間です。 TTLの有効期限が切れると、キャッシュエントリはキャッシュから削除されます。 cacheTTLのデフォルト値は5000ミリ秒(5秒)です。
キャッシングについて説明することは他にもありますが、それは問題とは無関係です。
キャッシュクラス の次のコードは、キャッシュポリシーを詳細に示しています。
152 //コンテンツはキャッシュされませんが、メタデータサイズが必要です
15 長いです delta = cacheEntry . getSize ();
154 サイズ。 addAndGet (delta);
156 もし (サイズ. get ()> maxSize){
157 //速度のためにリソースを順不同で処理する。取引キャッシュ
158 //効率(若いエントリは古いエントリよりも先に削除されます
159 // ones)これはクリティカルパス上にあるため
16 //リクエスト処理
161 長いです targetSize =
162 maxSize *(100-TARGET_FREE_PERCENT_GET)/ 100;
16 長いです newSize = evict (
164 targetSize、resourceCache . values (). iterator ());
165 もし (newSize> maxSize){
166 //このリソースに十分なスペースを作成できません
167 //キャッシュから削除する
168removeCacheEntry (path);
169 log . warn (sm . getString ( "cache.addFail"、path));
17 }
171 }
WebResourceをロードするとき、コードはキャッシュの新しいサイズを計算します。計算されたサイズがデフォルトの最大サイズより大きい場合、1つ以上のキャッシュされたエントリを削除する必要があります。そうでない場合、新しいサイズは最大サイズを超えます。そのため、コードは「targetSize」を計算します。これは、キャッシュが(最適として)維持したいサイズであり、デフォルトでは最大の95%です。このtargetSizeに到達するには、エントリをキャッシュから削除/削除する必要があります。これは、次のコードを使用して行われます。
215 プライベート長いです evict(長いです targetSize、 イテレータ < CachedResource > iter){
217 長いです now = System . currentTimeMillis ();
219 長いです newSize =サイズ。 get ();
221 しながら (newSize> targetSize && iter . hasNext ()){
222CachedResource resource = iter . next ();
224 // TTL内でチェックされたものを期限切れにしない
225 もし (resource . getNextCheck ()> now){
226 持続する;
227 }
229 //キャッシュからエントリを削除する
2removeCacheEntry (resource . getWebappPath ());
232 newSize = size . get ();
2 }
235 帰る newSize;
236 }
そのため、キャッシュエントリは、そのTTLが期限切れになり、targetSizeにまだ到達していないときに削除されます。
キャッシュエントリを削除してキャッシュを解放しようとすると、コードは次のようになります。
165 もし (newSize> maxSize){
166 //このリソースに十分なスペースを作成できません
167 //キャッシュから削除する
168removeCacheEntry (path);
169 log . warn (sm . getString ( "cache.addFail"、path));
17 }
したがって、キャッシュを解放しようとしてもサイズが最大値を超えている場合、解放できないことを示す警告メッセージが表示されます。
cache.addFail=Unable to add the resource at [{0}] to the cache for web application [{1}] because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache
警告メッセージが示すように、問題は
期限切れのキャッシュエントリを削除した後に利用可能な空き領域が不足しています-キャッシュの最大サイズを増やすことを検討してください
Webアプリケーションが短い時間(5秒)内に多くのキャッシュされていないwebResources(キャッシュの最大値、デフォルトでは10MB)をロードすると、警告が表示されます。
紛らわしい部分は、Tomcat 7が警告を表示しなかったことです。これは、このTomcat 7コードが原因です。
1606 //キャッシュに新しいエントリを追加
1607 同期された (キャッシュ){
1608 //キャッシュサイズを確認し、大きすぎる場合は要素を削除する
1609 もし ((cache . lookup (name)== ヌル)&& cache . allocate (entry.size)){
161 キャッシュ。 ロード (エントリ);
1611 }
1612 }
と組み合わせ:
231 ながら (toFree> 0){
232 もし (試行== maxAllocateIterations){
2 //あきらめ、現在のキャッシュは変更されません
234 帰るfalse;
235 }
そのため、Tomcat 7はキャッシュを解放できない場合に警告をまったく出力しませんが、Tomcat 8は警告を出力します。
そのため、Tomcat 7と同じデフォルトのキャッシュ構成でTomcat 8を使用していて、Tomcat 8で警告を受け取った場合、Tomcat 7の(および私の)キャッシュ設定は警告なしにパフォーマンスが低下していました。
複数の解決策があります。
ここで説明されているとおり: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html
<Resources cacheMaxSize="XXXXX" />
のContext
要素内に$CATALINA_BASE/conf/context.xml
を追加します。ここで、「XXXXX」は増加したキャッシュサイズを表し、キロバイト単位で指定されます。デフォルトは10240(10メガバイト)なので、これよりも大きいサイズを設定します。
最適な設定に調整する必要があります。トラフィック/リソースリクエストが突然増加すると、問題が再発する可能性があることに注意してください。
新しいキャッシュサイズを試すたびにサーバーを再起動する必要を回避するために、JMXを使用して再起動せずにサーバーを変更できます。
JMXを有効にする に、これをServer
要素内の$CATALINA_BASE/conf/server.xml
に追加します:<Listener className="org.Apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" />
および https://Tomcat.Apache.orgからcatalina-jmx-remote.jar
をダウンロードします/download-80.cgi を$CATALINA_HOME/lib
に配置します。次に、jConsole(デフォルトでJava JDKに付属)を使用してJMX経由でサーバーに接続し、サーバーの実行中にキャッシュサイズを増やす設定の設定を調べます。これらの設定の変更はすぐに反映されるはずです。
cacheTtl
値を5000ミリ秒未満に下げ、最適な設定に調整します。
例:<Resources cacheMaxSize="2000" />
これは、キャッシュを使用せずにRAMに入れて埋めることに効果的になります。
org.Apache.catalina.webresources.Cache
のロガーを無効にするようにロギングを構成します。
Tomcatでのロギングの詳細については、 http://Tomcat.Apache.org/Tomcat-8.0-doc/logging.html
cachingAllowed
をfalse
に設定すると、キャッシュを無効にできます。 <Resources cachingAllowed="false" />
Tomcat 8のベータ版では、JMXを使用してキャッシュを無効にしていたことを思い出すことができます。 (正確な理由はわかりませんが、server.xmlを介してキャッシュを無効にすると問題が発生する可能性があります。)
キャッシュに余裕がある静的リソースがもっとあります。次のいずれかを実行できます。
詳細については、これらの設定オプションに関する ドキュメント を参照してください。
それが他の誰かを助ける場合には、私がこの問題を解決することができた唯一の方法はconf/logging.properties
に以下を追加することでした:
org.Apache.catalina.webresources.Cache.level = SEVERE
これにより、「リソースを追加できません」というログが除外されます。これは警告レベルです。