Oracle Advanced Queue - 消费率中的性能问题

时间:2015-10-22 16:16:23

标签: java oracle performance advanced-queuing

我们在Oracle数据库环境中使用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客户端发布了1000000条带有2380 TPS的消息。我们使用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();

您对我们如何改善消费者的表现有什么建议吗?

1 个答案:

答案 0 :(得分:0)

您使用Timer可能是您的主要问题。 Timer定义为:

  

对应于每个Timer对象的是一个后台线程,用于按顺序执行所有计时器的任务。计时器任务应该快速完成。 如果一个计时器任务需要很长的时间才能完成,那么#" hogs"计时器的任务执行线程。反过来,这可以延迟后续任务的执行,这可能会导致" 并且当违规任务最终完成时(如果有的话)快速连续执行

我建议您使用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);
}