0

マルチスレッドアプリケーションがあり、ロギングにlog4jを使用しています。Windows 7 / Intelラップトップでアプリケーションをテストすると、問題なく動作します。しかし、同じアプリケーションを本番サーバー(solaris / sparc)にデプロイすると、10分間動作してから、速度が低下し始めます(非常に低速)。プロファイラーを使用してスレッドの状態を確認しました。スレッドダンプのlog4j操作が原因で、多くのスレッドがブロックされました。私も非同期アペンダーを使用していますが、成功した結果を得ることができません。何か推測?

ここにいくつかのダンプがあります:

"pool-7-thread-105" - Thread t@22939
   java.lang.Thread.State: BLOCKED
    at org.apache.log4j.Category.callAppenders(Category.java:204)
    - waiting to lock <794f2dae> (a org.apache.log4j.spi.RootLogger) owned by "pool-7-thread-112" t@22946
    at org.apache.log4j.Category.forcedLog(Category.java:391)
    at org.apache.log4j.Category.info(Category.java:666)

"pool-7-thread-112" - Thread t@22946
   java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(Unknown Source)
    at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
    at java.io.BufferedOutputStream.flush(Unknown Source)
    - locked <5fcbc329> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(Unknown Source)
    - locked <19e9d0c5> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
    at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
    at sun.nio.cs.StreamEncoder.flush(Unknown Source)
    - locked <3680c465> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flush(Unknown Source)
    at org.apache.log4j.helpers.QuietWriter.flush(QuietWriter.java:59)
    at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:324)
    at org.apache.log4j.WriterAppender.append(WriterAppender.java:162)
    at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
    - locked <3fddded7> (a org.apache.log4j.ConsoleAppender)
    at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
    at org.apache.log4j.Category.callAppenders(Category.java:206)
    - locked <794f2dae> (a org.apache.log4j.spi.RootLogger)
    at org.apache.log4j.Category.forcedLog(Category.java:391)
    at org.apache.log4j.Category.info(Category.java:666)

また、log4j.xml-バージョン1.2.17

<appender name="scripts" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="threshold" value="INFO"/>
    <param name="file" value="log/script.log"/>
    <param name="DatePattern" value="'.'yyyy-MM-dd"/>
    <layout class="org.apache.log4j.EnhancedPatternLayout">
        <param name="ConversionPattern"
               value="%-6p[%-d{ISO8601}] [%t] %m (%F:%L) %n"/>
    </layout>
</appender>

<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
    <param name="threshold" value="INFO"/>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%-6p[%-d{ISO8601}] [%t] %m (%F:%L) %n"/>
    </layout>
</appender>

<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
    <param name="BufferSize" value="5000"/>
    <appender-ref ref="scripts"/>
</appender>

<root>
    <priority value="debug"/>
    <appender-ref ref="stdout"/>
    <appender-ref ref="ASYNC"/>
</root>

4

2 に答える 2

2

スタックダンプから判断すると、何かがflush()を呼び出しているので、BufferedOutputStreamを使用することの多くの「良さ」を否定します。フラッシュを回避する方法を理解できれば、スループットが向上します。

デビッドシュワルツはこうコメントしています:

Windowsは、パフォーマンスを向上させる方法として、ファイルフラッシュを実際に尊重しないことで有名です。SolarisとLinuxは実際にフルフラッシュを実行します。これは、プラットフォームに依存するパフォーマンスの違いを説明するのに役立つ場合があります。

(私はそれを知りませんでした。そしてそうです。)

WriterAppenderでimmediateFlushをオフにすると役立つ場合があります

優れたアドバイス。

于 2013-01-18T09:08:53.073 に答える
2

したがって、ログに記録しようとしているスレッドはブロックされます。なんで?ログ スレッドが で現在ブロックされているためjava.io.FileOutputStream.writeBytes(Native Method)です。これは、ログの対象 (ファイルなど) が、実行されるログの量に追いつかないことを強く示唆しています。

これをトラブルシューティングする方法は、ログがどこに向かっているのかを調べることから始めることです。ファイルに送信する場合、そのファイルは高速なローカル ファイル システム上にあるか? ディスク I/O は問題ですか?

I/O でブロックしないロギング スキームを使用することをお勧めします。必要はありません。スレッドがディスク I/O を実行している間に、他のスレッドが内部キューにログを記録できます。ただし、ロギング レートが I/O レートを超える場合は、最終的に何らかの方法でロギングがメモリに蓄積されるのを停止する必要があり、そのためにはスレッドをブロックするか、ログ エントリを破棄する必要があります。とはいえ、ログを取りすぎたり、深刻な I/O パフォーマンスの問題 (混雑したネットワークでの NFS 経由でのログ記録など) を抱えていたり、何らかの方法でファイルのバッファリングを無効にしたりしていない限り、これは問題にはなりません。

于 2013-01-18T09:02:31.690 に答える