Java JMS(ActiveMQ)性能
我有一个Java应用程序,其中有许多组件通过JMS(ActiveMQ)进行通信。目前,应用程序和JMS集线器位于同一台服务器上,尽管我们最终计划拆分组件以实现可伸缩性。目前,我们在性能方面遇到了一些重大问题,这些问题似乎都围绕着JMS,最值得注意的是,这个问题的焦点是将消息发布到主题所需的时间 我们有大约50个动态创建的主题,用于应用程序组件之间的通信。一个组件从表中读取记录并一次处理一条记录,处理过程包括创建JMS对象消息并将其发布到其中一个主题。此处理无法跟上记录写入源表的速度~23/秒,因此我们更改了处理以创建JMS对象消息并将其添加到队列中。创建了一个新线程,该线程从该队列读取消息并将消息发布到相应的主题。显然,这并没有加快处理速度,但它确实允许我们通过查看队列的大小来了解我们落后了多少 在一天开始时,没有消息通过整个系统,这将从第一个小时通过集线器的156000(433/秒)消息迅速增加到第三个小时的2100000(582/秒),然后保持在该水平。在第一个小时开始时,从组件读取数据库表记录的消息发布将保持不变。但是,到该小时结束时,队列中有2000条消息等待发送,到第三个小时,队列中有9000条消息 下面是发送JMS消息的代码的适当部分,非常感谢关于我们做错了什么或如何改进性能的任何建议。查看web上的统计信息,JMS应该能够轻松处理每秒约1000-2000条大消息或每秒约10000条小消息。我们的信息大约是500个字节,所以我想象坐在这个范围的某个地方。 获取发布者的代码:Java JMS(ActiveMQ)性能,java,jms,activemq,Java,Jms,Activemq,我有一个Java应用程序,其中有许多组件通过JMS(ActiveMQ)进行通信。目前,应用程序和JMS集线器位于同一台服务器上,尽管我们最终计划拆分组件以实现可伸缩性。目前,我们在性能方面遇到了一些重大问题,这些问题似乎都围绕着JMS,最值得注意的是,这个问题的焦点是将消息发布到主题所需的时间 我们有大约50个动态创建的主题,用于应用程序组件之间的通信。一个组件从表中读取记录并一次处理一条记录,处理过程包括创建JMS对象消息并将其发布到其中一个主题。此处理无法跟上记录写入源表的速度~23/秒,因
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实现也是一种选择
谢谢,
James我们没有使用ActiveMQ,但是我们遇到了类似的问题,我们发现问题出在后端处理上,而不是Java端。这里可能存在多个问题:
很高兴知道Karianna提出的问题的答案。现在还不是100%清楚您在哪里体验到了缓慢的性能,但您所描述的似乎是发布消息的缓慢。是否每次发布邮件时都要创建新的发布者?如果是这样,这是非常低效的,你应该考虑创建一个出版商,并反复使用它来发送消息。此外,如果您正在发送持久性消息,那么您可能正在使用同步发送到代理。您可能需要考虑使用异步发送来加快速度。有关更多信息,请参阅关于的文档 此外,消费者的表现如何?使用了多少消费者?他们是否能够跟上消息发布的速度 此外,您正在使用的代理配置是什么?有没有调整过
Bruce虽然这是一个老问题,但有一条非常重要的建议缺失了:
- 调查您拥有的主题和队列数量李>
我遇到了类似的情况,每秒有数千条市场数据消息。当我天真地将每条消息转储到特定于市场工具的通道中时,服务器能够在向消息生产者吐出错误消息之前站立大约一个小时。我将设计更改为只有一个通道“MARKET_DATA”,然后在所有生成的消息上设置标题属性,并在消费者端设置选择器以仅选择我想要的消息。请注意,我的选择器使用类似SQL的语法,并在服务器上运行。。。(是的,让我们跳过CEP营销炒作) 您正在使用事务吗?您对队列有什么配置?他们真的在排队吗?还是话题?这么多问题:)。ActiveMQ的哪个版本?独立的?在应用服务器上?除非默认使用事务,否则我们不会显式使用事务。我们不在集线器上创建任何配置,主题是使用以下命令动态创建的:topic=(ActiveMQTopic)this.initialContext.lookup(“dynamicTopics/”+topicName);我们使用在独立实例中运行的ActiveMQ版本5.3.2。那么这个问题是怎么回事?你解决了吗?我认为没有处理问题。该应用程序运行在4 CPU服务器上,运行速度约为50%,最高不超过70%。将消息添加到队列并将其提取的代码非常简单。我已将其添加到我的帖子中。