1

Oracle DB 環境で Oracle Advanced Queue を使用してパフォーマンス テストを実行しました。次のスクリプトを使用して、キューとキュー テーブルを作成しました。

    BEGIN

    DBMS_AQADM.create_queue_table(
          queue_table => 'verisoft.qt_test', 
          queue_payload_type => 'SYS.AQ$_JMS_MESSAGE', 
          sort_list => 'ENQ_TIME', 
          multiple_consumers => false, 
          message_grouping => 0, 
          comment =>  'POC Authorizations Queue Table - KK',
          compatible => '10.0', 
          secure => true);

    DBMS_AQADM.create_queue(
          queue_name => 'verisoft.q_test', 
          queue_table => 'verisoft.qt_test', 
          queue_type => dbms_aqadm.NORMAL_QUEUE, 
          max_retries => 10, 
          retry_delay => 0, 
          retention_time => 0, 
          comment => 'POC Authorizations Queue - KK'); 

    DBMS_AQADM.start_queue('q_test');
    END;

    /

PL/SQL クライアントを使用して、2380 TPS で 1000000 メッセージを発行しました。また、Oracle JMS API クライアントを使用して、292 TPS で 1000000 メッセージを消費しました。コンシューマーの速度はパブリッシャーよりも約 10 倍遅く、その速度は私たちの要件を満たしていません。

以下は、メッセージを消費するために使用する Java コードの一部です。

    if (q == null) initializeQueue();
    System.out.println(listenerID + ": Listening on queue " + q.getQueueName() + "...");
    MessageConsumer consumer = sess.createConsumer(q);

    for (Message m; (m = consumer.receive()) != null;) {
        new Timer().schedule(new QueueExample(m), 0);
    }

    sess.close();
    con.close();

消費者側でパフォーマンスを向上させる方法について何か提案はありますか?

4

1 に答える 1

0

タイマーの使用が主な問題である可能性があります。定義は次のTimerとおりです。

各 Timer オブジェクトに対応するのは、タイマーのすべてのタスクを順番に実行するために使用される単一のバックグラウンド スレッドです。タイマー タスクはすぐに完了する必要があります。タイマー タスクの完了に時間がかかりすぎると、タイマーのタスク実行スレッドが「占有」されます。これにより、後続のタスクの実行が遅延する可能性があり、問題のあるタスクが最終的に完了すると、「まとまり」、立て続けに実行される可能性があります。

ThreadPoolを使用することをお勧めします。

// My executor.
ExecutorService executor = Executors.newCachedThreadPool();

public void test() throws InterruptedException {
    for (int i = 0; i < 1000; i++) {
        final int n = i;
        // Instead of using Timer, create a Runnable and pass it to the Executor.
        executor.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("Run " + n);
            }

        });

    }
    executor.shutdown();
    executor.awaitTermination(1, TimeUnit.DAYS);
}
于 2015-10-22T16:27:52.170 に答える