我们在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();
您对我们如何改善消费者的表现有什么建议吗?
答案 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);
}