Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JMS(ActiveMQ)性能_Java_Jms_Activemq - Fatal编程技术网

Java JMS(ActiveMQ)性能

Java JMS(ActiveMQ)性能,java,jms,activemq,Java,Jms,Activemq,我有一个Java应用程序,其中有许多组件通过JMS(ActiveMQ)进行通信。目前,应用程序和JMS集线器位于同一台服务器上,尽管我们最终计划拆分组件以实现可伸缩性。目前,我们在性能方面遇到了一些重大问题,这些问题似乎都围绕着JMS,最值得注意的是,这个问题的焦点是将消息发布到主题所需的时间 我们有大约50个动态创建的主题,用于应用程序组件之间的通信。一个组件从表中读取记录并一次处理一条记录,处理过程包括创建JMS对象消息并将其发布到其中一个主题。此处理无法跟上记录写入源表的速度~23/秒,因

我有一个Java应用程序,其中有许多组件通过JMS(ActiveMQ)进行通信。目前,应用程序和JMS集线器位于同一台服务器上,尽管我们最终计划拆分组件以实现可伸缩性。目前,我们在性能方面遇到了一些重大问题,这些问题似乎都围绕着JMS,最值得注意的是,这个问题的焦点是将消息发布到主题所需的时间

我们有大约50个动态创建的主题,用于应用程序组件之间的通信。一个组件从表中读取记录并一次处理一条记录,处理过程包括创建JMS对象消息并将其发布到其中一个主题。此处理无法跟上记录写入源表的速度~23/秒,因此我们更改了处理以创建JMS对象消息并将其添加到队列中。创建了一个新线程,该线程从该队列读取消息并将消息发布到相应的主题。显然,这并没有加快处理速度,但它确实允许我们通过查看队列的大小来了解我们落后了多少

在一天开始时,没有消息通过整个系统,这将从第一个小时通过集线器的156000(433/秒)消息迅速增加到第三个小时的2100000(582/秒),然后保持在该水平。在第一个小时开始时,从组件读取数据库表记录的消息发布将保持不变。但是,到该小时结束时,队列中有2000条消息等待发送,到第三个小时,队列中有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实现也是一种选择

谢谢,


James

我们没有使用ActiveMQ,但是我们遇到了类似的问题,我们发现问题出在后端处理上,而不是Java端。这里可能存在多个问题:

  • 处理来自队列的消息的程序可能很慢(例如大型机上的CICS),它可能无法跟上发送到队列的消息。一种可能的解决方案是提高处理能力(或优化处理消息的后端代码)
  • 检查队列上的消息,有时队列上有许多未提交的有毒消息,我们使用单独的队列来处理这些消息

  • 很高兴知道Karianna提出的问题的答案。

    现在还不是100%清楚您在哪里体验到了缓慢的性能,但您所描述的似乎是发布消息的缓慢。是否每次发布邮件时都要创建新的发布者?如果是这样,这是非常低效的,你应该考虑创建一个出版商,并反复使用它来发送消息。此外,如果您正在发送持久性消息,那么您可能正在使用同步发送到代理。您可能需要考虑使用异步发送来加快速度。有关更多信息,请参阅关于的文档

    此外,消费者的表现如何?使用了多少消费者?他们是否能够跟上消息发布的速度

    此外,您正在使用的代理配置是什么?有没有调整过


    Bruce

    虽然这是一个老问题,但有一条非常重要的建议缺失了:

    • 调查您拥有的主题和队列数量
    ActiveMQ将订阅主题保留在单独的线程中。特别是,当您有大量不同的主题时,这将拖累任何服务器。考虑改用JMS选择器


    我遇到了类似的情况,每秒有数千条市场数据消息。当我天真地将每条消息转储到特定于市场工具的通道中时,服务器能够在向消息生产者吐出错误消息之前站立大约一个小时。我将设计更改为只有一个通道“MARKET_DATA”,然后在所有生成的消息上设置标题属性,并在消费者端设置选择器以仅选择我想要的消息。请注意,我的选择器使用类似SQL的语法,并在服务器上运行。。。(是的,让我们跳过CEP营销炒作)

    您正在使用事务吗?您对队列有什么配置?他们真的在排队吗?还是话题?这么多问题:)。ActiveMQ的哪个版本?独立的?在应用服务器上?除非默认使用事务,否则我们不会显式使用事务。我们不在集线器上创建任何配置,主题是使用以下命令动态创建的:topic=(ActiveMQTopic)this.initialContext.lookup(“dynamicTopics/”+topicName);我们使用在独立实例中运行的ActiveMQ版本5.3.2。那么这个问题是怎么回事?你解决了吗?我认为没有处理问题。该应用程序运行在4 CPU服务器上,运行速度约为50%,最高不超过70%。将消息添加到队列并将其提取的代码非常简单。我已将其添加到我的帖子中。