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定义如下:

对应于每个 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 回答