6

多数の永続キュー (250) 1000 永続 TextMessages 10 KB で ActiveMQ を使用すると問題が発生します。

シナリオでは、これらのメッセージが消費されるまで、長期間 (数日) にわたってストレージに保持する必要があります (大量のデータが多数のコンシューマーに配布するためにステージングされ、数日間オフラインになる可能性があります)。

Persistence Store がこれらのメッセージでいっぱいになった後、ブローカーの再起動 後、30 秒後に #checkpoint が呼び出されるまで、いくつかのキューを参照/消費できます。

この呼び出しにより、ブローカは使用可能なすべてのメモリを使用し、キューの参照/消費などの他のタスクのためにメモリを解放することはありません。内部的に、MessageCursor はメモリが不足していると判断したようで、ブラウザ/コンシューマへのキュー コンテンツの配信を停止します。

=> 構成によってこの動作を回避する方法はありますか、それともバグですか?

期待されるのは、すべての状況で任意のキューを消費/参照できることです。

以下の設定は現在しばらくの間本番環境にあり、ActiveMQ のドキュメントに記載されているいくつかの推奨事項が適用されています (宛先ポリシー、systemUsage、永続ストア オプションなど)。

  • 動作は ActiveMQ: 5.11.2、5.13.0、および 5.5.1 でテストされています。
  • メモリ設定: Xmx=1024m
  • Java: 1.8 または 1.7
  • OS: Windows、MacOS、Linux
  • PersistenceAdapter: KahaDB または LevelDB
  • ディスク: 十分な空き容量 (200 GB) と物理メモリ (最大 16 GB)。

上記の設定に加えて、ブローカーには次の設定を使用します (ちなみに、memoryLimit を 1mb のような低い値に変更しても状況は変わりません)。

<destinationPolicy>
    <policyMap>
        <policyEntries>
            <policyEntry queue=">" producerFlowControl="false" optimizedDispatch="true" memoryLimit="128mb" timeBeforeDispatchStarts="1000">
                <dispatchPolicy>
                    <strictOrderDispatchPolicy />
                </dispatchPolicy>
                <pendingQueuePolicy>
                    <storeCursor />
                </pendingQueuePolicy>
            </policyEntry>
        </policyEntries>
    </policyMap>
</destinationPolicy>
<systemUsage>
    <systemUsage sendFailIfNoSpace="true">
        <memoryUsage>
            <memoryUsage limit="500 mb" />
        </memoryUsage>
        <storeUsage>
            <storeUsage limit="80000 mb" />
        </storeUsage>
        <tempUsage>
            <tempUsage limit="1000 mb" />
        </tempUsage>
    </systemUsage>
</systemUsage>

memoryUsage と利用可能なヒープ領域の違いに応じて、 destinationPolicy のcursorMemoryHighWaterMarkを150または600などのより高い値に設定すると、回避策として状況が少し緩和されますが、これは実際には本番システムのオプションではありません。見る。

メモリから決して解放されない ActiveMQTextMessage インスタンスを示す Oracle Mission Control からの情報を含む画面:

http://goo.gl/EjEixV

4

2 に答える 2

2

(キュー) 宛先 policyEntry を変更することで、問題を解決できます。

徹底的な調査 (ActiveMQ ソース コードの変更なし) の結果、現時点では、#checkpoint/cleanup プロセスと参照/消費キューの両方に使用される単一の memoryLimit パラメーターによって定義された制限を受け入れる必要があるという結果になりました。

1.) メモリ

#checkpoint/cleanup ワークフロー中の送信先ごとのメッセージ キャッシュと、メッセージを閲覧/消費するための要件の両方をサポートするために、はるかに高い memoryLimit を (より高い max-heap と共に) 使用しても問題はありません。

ただし、このシナリオではメモリを増やすことはできません。1024m の最大ヒープと 500m のメモリ制限に対処する必要があります。

これに加えて、特定のオフライン/非アクティブな消費者シナリオと一緒に数百/数千の保留中のメッセージを含むより永続的なキューのためだけに、常により高いメモリ制限を設定することについて詳しく説明する必要があります (IMHO)。

2.) 永続的なアダプター

異なるタイプの永続ストア (KahaDB、LevelDB、JDBC-PostgreSQL) を切り替えても動作は変わらないため、問題の原因として永続アダプターを除外しました。

KahaDB でのデバッグ セッション中に、通常のチェックポイント処理も見られます。ストレージは期待どおりに管理されています。

3.) 宛先ポリシー / 有効期限チェック

問題の実際の原因であるキャッシュと有効期限チェックを無効にすると、問題は完全に解消されます。

対応するプロパティは文書化されており、メッセージの優先度に関する素晴らしいブログ記事があり、シナリオに非常に適した説明があります。

policyEntry に useCache="false" と expireMessagesPeriod="0" を追加しただけです。

<destinationPolicy>
    <policyMap>
        <policyEntries>
            <policyEntry queue=">" producerFlowControl="false" optimizedDispatch="true" memoryLimit="128mb" timeBeforeDispatchStarts="1000"
                                   useCache="false" expireMessagesPeriod="0">
                <dispatchPolicy>
                    <strictOrderDispatchPolicy />
                </dispatchPolicy>
                <pendingQueuePolicy>
                    <storeCursor />
                </pendingQueuePolicy>
            </policyEntry>
        </policyEntries>
    </policyMap>
</destinationPolicy>

メモリ内キャッシュを使用せず、メッセージの有効期限をチェックしない場合、結果は明らかです。

メッセージの有効期限もメッセージの優先度も使用せず、現在のメッセージのディスパッチは十分に高速であるため、このトレードオフはシステムの制限に関して許容されます。

また、特定のワークフロー中のメモリ消費に対して明確に定義されたプリフェッチ制限についても考慮する必要があります。このシナリオのメッセージ サイズは、2 バイトから最大約 2 バイトです。100 KB であるため、より多くの個々の policyEntries とクライアント コンシューマー構成は、パフォーマンスとメモリ使用に関するシステム動作を最適化するのに役立ちます ( http://activemq.apache.org/per-destination-policies.htmlを参照してください)。

于 2016-01-13T10:30:31.703 に答える