Tomcat 8スロー-org.apache.catalina.webresources.Cache.getResourceリソースを追加できません


111

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"
/>  

ありがとう。


返信はありません-この問題を抱えているのは私だけでしょう。
iainmac999 2014年

2
ソリューションはここにある:serverfault.com/questions/644415/...
ドミトリー

1
Tomcat 8コンテキストで欠落している属性に関して、以下は移行ガイドからの抜粋です(強調鉱山):「リソースのリファクタリングは、デフォルトのコンテキスト実装(org.apache.catalina.core .StandardContext)。次の属性、Webアプリケーションによって使用されるリソース実装を介して構成できるようになりました。詳細については、関連する移行GUIDをご覧ください。
informatik01

@ iainmac999は2年後に正しい答えを選択したことがないので、それが両方の方法で機能することに同意できますか?
davidjmcclelland 2017年

回答:


161

あなたには$CATALINA_BASE/conf/context.xml前に、以下の追加ブロック</Context>

<Resources cachingAllowed="true" cacheMaxSize="100000" />

詳細:http : //tomcat.apache.org/tomcat-8.0-doc/config/resources.html


11
個々のリーダーは、そのcacheMaxSize値を100 MB未満に調整したいと思うでしょう。
Eric Spiegelberg、2016

これまでのところ、エラーメッセージはコンソールログを殺到していました。今は明らかです。ありがとう
Abubacker Siddik

152

Tomcat 7から8にアップグレードするときにも同じ問題が発生しました。キャッシュに関するログ警告が大量に連続して大量に発生します。

1.短い答え

これをのContextxml要素内に追加します$CATALINA_BASE/conf/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メガバイト)なので、これよりも大きいサイズを設定します。警告が消える最適な設定に調整するよりも。交通量の多い状況では警告が表示される場合があることに注意してください。

1.1原因(簡単な説明)

この問題は、キャッシュエントリがそれらのエントリのTTLより小さいため、Tomcatがターゲットキャッシュサイズに到達できないことが原因で発生します。そのため、Tomcatは期限切れになる可能性があるほど十分なキャッシュエントリを持っていませんでした。キャッシュエントリが新鮮すぎるため、十分なキャッシュを解放できず、警告が出力されました。

この状況ではTomcat 7が警告を出力しなかったため、問題はTomcat 7では発生しませんでした。(通知されずに、あなたと私が不適切なキャッシュ設定を使用する原因になります。)

この問題は、キャッシュのサイズやTTLと比較して、比較的短い期間にリソース(通常は静的)に対する比較的大量のHTTPリクエストを受信したときに発生します。キャッシュが最大(デフォルトでは10 mb)に達し、サイズの95%を超えて新しいキャッシュエントリがある場合(新しいとは、キャッシュ内で5秒未満を意味します)、Tomcatが試行する各webResourceに対して警告メッセージが表示されますキャッシュにロードします。

1.2オプション情報

再起動せずに実行中のサーバーでcacheMaxSizeを調整する必要がある場合は、JMXを使用します。

最も簡単な修正は<Resources cachingAllowed="false" />、キャッシュを完全に無効にすることです:、しかしそれは次善の策なので、今説明したようにcacheMaxSizeを増やします。

2.長い答え

2.1背景情報

A WebSourceは、 Webアプリケーション内のファイルまたはディレクトリです。パフォーマンス上の理由から、TomcatはWebSourceをキャッシュできます。静的リソースキャッシュ(合計ですべてのリソース)の最大値は、デフォルトで10240 kbyte(10 mbyte)です。webResourceは、webResourceが要求されたときに(たとえば、静的な画像を読み込むときに)キャッシュに読み込まれ、キャッシュエントリと呼ばれます。すべてのキャッシュエントリにはTTL存続可能時間)があり、これはキャッシュエントリがキャッシュ内に留まることができる時間です。TTLが期限切れになると、キャッシュエントリはキャッシュから削除されます。cacheTTLのデフォルト値は5000ミリ秒(5秒)です。

キャッシングについては他にも説明がありますが、それは問題には関係ありません。

2.2原因

Cacheクラスの次のコードは、キャッシュポリシーを詳細に示しています。

152   //コンテンツはキャッシュされませんが、メタデータサイズ
153 が必要です。長いデルタ= cacheEntry。getSize();
154 サイズ。addAndGet(デルタ);
156 であれば(サイズ取得()> maxSizeの)は、{
157の //プロセスリソースは、速度のために順序付けられていません。 これは160のクリティカルパス上にあるため、キャッシュを
158 //効率(若いエントリは古い
159 // エントリの前に削除される可能性があります) //要求処理161 long targetSize = 162 maxSize *(100-TARGET_FREE_PERCENT_GET)/ 100;



163 長い NewSizeパラメータ= 追い出し
164 。はTargetSize、resourceCache ()。イテレータ())。
165 if(newSize> maxSize){
166 //このリソースに十分なスペースを作成できません
167 //キャッシュから削除します
168 removeCacheEntry(path);
169 ログ。警告(SM のgetString( "cache.addFail"パス))。
170 }
171 }

webResourceをロードするとき、コードはキャッシュの新しいサイズを計算します。計算されたサイズがデフォルトの最大サイズより大きい場合、1つ以上のキャッシュされたエントリを削除する必要があります。そうでない場合、新しいサイズは最大サイズを超えます。したがって、コードは「targetSize」を計算します。これは、キャッシュが(最適値として)下に留まりたいサイズで、デフォルトでは最大値の95%です。このtargetSizeに到達するには、エントリをキャッシュから削除または削除する必要があります。これは、次のコードを使用して行われます。

215   private  long evictlong targetSize、Iterator < CachedResource > iter){ 
217 long now = System。currentTimeMillis();
219 長い newSize =サイズ。get();
221 while(newSize> targetSize && iter。hasNext()){
222 CachedResource resource = iter。();
224 // DOはTTL内でチェックされている何も期限切れにならない
225 場合(リソース。getNextCheck今()>を){
226 続ける ;
227 }
229 //キャッシュからエントリを削除する
230 removeCacheEntry(リソース。getWebappPathを())。
232 newSize =サイズ。get();
233 }
235 return newSize;
236 }

したがって、TTLが期限切れになり、targetSizeにまだ到達していない場合、キャッシュエントリは削除されます。

キャッシュエントリを削除してキャッシュを解放しようとすると、コードは次のようになります。

165   if(newSize> maxSize){ 
166 //このリソースに十分なスペースを作成できません
167 //キャッシュから削除します
168 removeCacheEntry(path);
169 ログ。警告(SM のgetString( "cache.addFail"パス))。
170 }

したがって、キャッシュを解放しようとした後もサイズが最大値を超えている場合は、解放できないという警告メッセージが表示されます。

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

2.3問題

警告メッセージが言うように、問題は

期限切れのキャッシュエントリを削除した後、使用可能な空き領域が不足しています-キャッシュの最大サイズを増やすことを検討してください

Webアプリケーションが多くのキャッシュされていないwebResources(約最大キャッシュ、デフォルトでは10mb)を短時間(5秒)内にロードすると、警告が表示されます。

混乱する部分は、Tomcat 7が警告を表示しなかったことです。これは単にこのTomcat 7コードが原因です。

1606は   キャッシュに新しいエントリを追加します。// 
1607年 同期(キャッシュ){
1608 大きすぎる場合//チェックキャッシュサイズ、および削除要素
1609 場合((キャッシュ。検索(名)== nullが)&&キャッシュ。割り当てる(entry.size) ){
1610 キャッシュ。ロード(エントリ);
1611 }
1612 }

と組み合わせ:

231   while(toFree> 0){ 
232 if(attempts == maxAllocateIterations){
233 //あきらめ、現在のキャッシュに変更を加えない
234 return false ;
235 }

したがって、Tomcat 7はキャッシュを解放できないときに警告をまったく出力しませんが、Tomcat 8は警告を出力します。

したがって、Tomcat 7と同じデフォルトのキャッシング構成でTomcat 8を使用していて、Tomcat 8で警告が表示された場合、Tomcat 7の(および私の)キャッシング設定は警告なしで十分に機能していませんでした。

2.4ソリューション

複数の解決策があります:

  1. キャッシュを増やす(推奨)
  2. TTLを下げる(非推奨)
  3. キャッシュログの警告を抑制します(非推奨)
  4. キャッシュを無効にする

2.4.1。キャッシュを増やす(推奨)

ここで説明するように: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有効にするには、これを要素$CATALINA_BASE/conf/server.xml内に追加し、httpsServer<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" />//tomcat.apache.org/download-80.cgi catalina-jmx-remote.jarからダウンロード してに配置します。次に、jConsole(デフォルトでJava JDKに付属)を使用してJMX経由でサーバーに接続し、サーバーの実行中に設定の設定を確認してキャッシュサイズを増やします。これらの設定の変更はすぐに反映されます。$CATALINA_HOME/lib

2.4.2。TTLを下げる(非推奨)

下げてcacheTtl最適な設定のための5000ミリ秒の曲よりも低く何かに値を。

例えば: <Resources cacheTtl="2000" />

これは、RAMを使用せずにRAMにキャッシュを格納し、それを埋めることに効果的です。

2.4.3。キャッシュログの警告を抑制します(非推奨)

のロガーを無効にするようにロギングを設定しorg.apache.catalina.webresources.Cacheます。

Tomcatへのログインに関する詳細情報:http : //tomcat.apache.org/tomcat-8.0-doc/logging.html

2.4.4。キャッシュを無効にする

あなたは、設定することで、キャッシュを無効にすることができますcachingAllowedfalse<Resources cachingAllowed="false" />

Tomcat 8のベータ版では、JMXを使用してキャッシュを無効にしていたことを覚えています。(正確な理由は不明ですが、server.xmlを介してキャッシュを無効にすることに問題がある可能性があります。)


キャッシュを増やしますか?私はそれがうまくいくとは思えません...私はこれを見ました:private long maxSize = 10 * 1024 * 1024; ソースで。grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/...
HoaPhan

tomcat8がキャッシュ警告をあふれさせる理由への答えを見つけましたか
PHP Avenger

@HoaPhan 10 * 1024 * 1024は、すべてのキャッシュの合計で最大10MBです。Webアプリケーションのトラフィックに応じて、これは数秒以内に到達できます。それを十分に増やすと、うまくいきます。
Devabc 2017

@PHPAvenger Tomcat 7はこの例ではまったく警告しませんでしたが、Tomcat 8は警告するため、警告機能と見なすことができます。問題は、警告が1回だけでなく、すべてのto-cacheリソース要求に対して警告されることです。特定の時間またはキャッシュターゲットヒットの後にのみ警告することは改善になるでしょう。
Devabc 2017

@Devabc完璧な答え!SOクラシック!
gaurav

9

キャッシュに余裕のある静的リソースがさらにあります。次のいずれかを実行できます。

  • キャッシュのサイズを増やす
  • キャッシュのTTLを減らす
  • キャッシュを無効にする

詳細については、これらの構成オプションのドキュメントを参照してください。


1
コメントをありがとう。例外の意味は理解しています。もちろん、リンク先のドキュメントも読みましたが、構成を変更せずにこれが7から8に変わる理由がわかりません。つまり、デフォルトのファイルシステムリソースハンドラーが8から7で変更を参照せずに異なるのはなぜですか。また、起動時のバグが報告され、おそらく修正されたのではないかと疑っています。
iainmac999 2014年

1
おそらく、移行ガイド、具体的にはtomcat.apache.org/migration-8.html#Web_application_resourcesを読んだことがあれば、状況はより明確になります。
マークトーマス

ドキュメントがa)このキャッシュに入れられるリソースとその理由(それについて多くの誤解がたくさんあります!)を説明し、b)さまざまな設定に与える影響(たとえば、各Webアプリのキャッシュ設定を盲目的に作成する)非常に大きいと大量のメモリを消費する可能性があります)、これを適切に調整する方法。また、アプリケーション自体が使用する静的リソースのキャッシュと、ユーザーエージェントが要求し、アプリケーションが配信するだけの静的ファイルとの間にコードと構成に違いがある場合にも役立ちます。
フォルカーク

4

これは、メッセージがログに表示される原因となる状態を解決しないという意味では解決策ではありませんが、次のコードをに追加することでメッセージを抑制できますconf/logging.properties

org.apache.catalina.webresources.Cache.level = SEVERE

これにより、「リソースを追加できません」ログが除外されます。これは、警告レベルです。

私の見解でWARNINGは、a は必ずしも対処する必要があるエラーではなく、必要に応じて無視できます。


8
はは。これは問題を解決しません。表示されないだけです。WTF!
T3rm1

これにより、それ自体で重大な問題になる可能性のある過剰なロギングの問題が解決されます。それは以前のTomcatバージョンの動作に戻り、多くの人にとって十分に機能するため、その意味で問題を「解決」します。これは、tomcatキャッシュを実際に調整する問題には対処していません。これは、devavacによる回答で非常にうまくカバーされています。
volkerk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.