Tomcat 7から8にアップグレードするときにも同じ問題が発生しました。キャッシュに関するログ警告が大量に連続して大量に発生します。
1.短い答え
これをのContext
xml要素内に追加します$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 evict(long 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ソリューション
複数の解決策があります:
- キャッシュを増やす(推奨)
- TTLを下げる(非推奨)
- キャッシュログの警告を抑制します(非推奨)
- キャッシュを無効にする
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。キャッシュを無効にする
あなたは、設定することで、キャッシュを無効にすることができますcachingAllowed
しfalse
。
<Resources cachingAllowed="false" />
Tomcat 8のベータ版では、JMXを使用してキャッシュを無効にしていたことを覚えています。(正確な理由は不明ですが、server.xmlを介してキャッシュを無効にすることに問題がある可能性があります。)