我有一个Java应用程序,其中有许多通过JMS(ActiveMQ)进行通信的组件。目前应用程序和JMS Hub位于同一台服务器上,尽管我们最终计划拆分组件的可伸缩性。目前,我们在性能方面存在重大问题,尤其是在JMS方面,最显着的是,这个问题的焦点在于向主题发布消息所花费的时间。JMS(ActiveMQ)性能
我们有大约50个动态创建的主题用于应用程序组件之间的通信。一个组件从表中读取记录并逐个处理它们,处理过程涉及创建JMS对象消息并将其发布到其中一个主题。这个处理跟不上记录写入源表的速度〜23/sec,所以我们改变了处理过程来创建JMS对象消息并将它添加到队列中。创建一个新线程,从该队列中读取并将消息发布到适当的主题。显然,这并不能加快处理速度,但它确实让我们看到了排队的大小后面到底有多远。
在一天的开始时间里,没有任何信息通过整个系统,在第一个小时内从1560000(433 /秒)信息通过集线器快速增加到第三个小时的2100000(582/sec)然后停留在那个水平。在第一个小时开始时,从数据库表中读取组件的消息发布的消息保持不变,但在那一小时结束时,在等待发送的队列中有2000条消息,并且在第3个小时的时间队列中有9000条消息在里面。
下面是发送JMS消息的代码的相关章节,关于我们做错了什么的建议或者我们如何改进这种性能非常感谢。查看Web上的统计信息JMS应该能够轻松处理〜1000-2000条大消息/秒或〜10000条小消息/秒。我们的消息每个都是500字节左右,所以我想可以坐在这个规模的中间。
代码用于获取出版商:
private JmsSessionPublisher getJmsSessionPublisher(String topicName) throws JMSException {
if (!this.topicPublishers.containsKey(topicName)) {
TopicSession pubSession = (ActiveMQTopicSession) topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQTopic topic = getTopic(topicName, pubSession);
// Create a JMS publisher and subscriber
TopicPublisher publisher = pubSession.createPublisher(topic);
this.topicPublishers.put(topicName, new JmsSessionPublisher(pubSession, publisher));
}
return this.topicPublishers.get(topicName);
}
发送消息:
JmsSessionPublisher jmsSessionPublisher = getJmsSessionPublisher(topicName);
ObjectMessage objMessage = jmsSessionPublisher.getSession().createObjectMessage(messageObj);
objMessage.setJMSCorrelationID(correlationID);
objMessage.setJMSTimestamp(System.currentTimeMillis());
jmsSessionPublisher.getPublisher().publish(objMessage, false, 4, 0);
代码这增加了消息到队列:
List<EventQueue> events = eventQueueDao.getNonProcessedEvents();
for (EventQueue eventRow : events) {
IEvent event = eventRow.getEvent();
AbstractEventFactory.EventType eventType = AbstractEventFactory.EventType.valueOf(event.getEventType());
String topic = event.getTopicName() + topicSuffix;
EventMsgPayload eventMsg = AbstractEventFactory.getFactory(eventType).getEventMsgPayload(event);
synchronized (queue) {
queue.add(new QueueElement(eventRow.getEventId(), topic, eventMsg));
queue.notify();
}
}
代码在螺纹去除的物品队列:
jmsSessionFactory.publishMessageToTopic(e.getTopic(), e.getEventMsg(), Integer.toString(e.getEventMsg().hashCode()));
publishMessageToTopic执行上面的'发送消息'代码。
如果您认为ActiveMQ可能不是最佳选择,那么其他JMS实现是一种选择。
谢谢
詹姆斯
您使用的是交易?你有什么配置的队列?他们真的排队吗?还是话题?这么多的问题 :)。什么版本的ActiveMQ?独立?在应用程序服务器上? – 2010-11-01 17:57:01
除非默认使用,否则我们不明确使用交易。我们不在hub上创建任何配置,而是使用以下命令动态创建主题:topic =(ActiveMQTopic)this.initialContext.lookup(“dynamicTopics /”+ topicName);我们使用运行在独立实例中的ActiveMQ版本5.3.2。 – James 2010-11-02 07:48:57
那么这个问题有什么问题?你解决了吗? – 2012-10-28 18:42:36