Производительность JMS (ActiveMQ) - PullRequest
1 голос
/ 01 ноября 2010

У меня есть Java-приложение с несколькими компонентами, взаимодействующими через JMS (ActiveMQ).В настоящее время приложение и JMS-концентратор находятся на одном сервере, хотя в конечном итоге мы планируем разделить компоненты для обеспечения масштабируемости.В настоящее время мы сталкиваемся с серьезными проблемами с производительностью, по-видимому, вокруг JMS, в первую очередь, и в центре внимания этого вопроса находится количество времени, которое требуется для публикации сообщения в теме.

У нас около 50 динамическисозданные темы, используемые для связи между компонентами приложения.Один компонент читает записи из таблицы и обрабатывает их по одной, обработка включает создание сообщения объекта JMS и публикацию его в одной из тем.Эта обработка не могла соответствовать скорости записи записей в исходную таблицу ~ 23 / сек, поэтому мы изменили обработку, чтобы создать сообщение объекта JMS и добавить его в очередь.Был создан новый поток, который прочитал из этой очереди и опубликовал сообщение в соответствующей теме.Очевидно, что это не ускоряет обработку, но позволяет нам увидеть, насколько далеко мы отставали, посмотрев на размер очереди.

В начале дня никакие сообщения не проходят через всю систему, это быстро увеличивает скорость с 1560000 (433 / сек) сообщений через концентратор в первый час до 2100000 (582 / сек) в 3-мчас, а затем оставаться на этом уровне.Однако в начале первого часа публикация сообщений из компонента, считывающего записи из таблицы базы данных, продолжается, к концу этого часа в очереди ожидается 2000 сообщений, ожидающих отправки, и к 3-му часу в очереди 9000 сообщений.в нем.

Ниже приведены соответствующие разделы кода, которые отправляют сообщения JMS, любые советы о том, что мы делаем неправильно или как мы можем улучшить эту производительность, высоко ценится.Просматривая статистику в Интернете, 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 выполняет приведенный выше код «Отправка сообщения».

Другие реализации JMS являются опцией, если все согласны с тем, что ActiveMQ может быть не лучшим вариантом.

Спасибо,

Джеймс

Ответы [ 3 ]

0 голосов
/ 19 ноября 2010

Неясно на 100%, где вы испытываете низкую производительность, но звучит так, как будто вы описываете медлительность публикации сообщений.Вы создаете нового издателя каждый раз, когда публикуете сообщение?Если это так, это ужасно неэффективно, и вы должны рассмотреть возможность создания одного издателя и использовать его снова и снова для отправки сообщений.Кроме того, если вы отправляете постоянные сообщения, то, вероятно, вы используете синхронные отправки брокеру.Возможно, вы захотите использовать асинхронные передачи для ускорения процесса.Для получения дополнительной информации см. Документ о Async Sends

Кроме того, как производительность потребителей?Сколько потребителей используется?Могут ли они идти в ногу со скоростью публикации сообщений?

Кроме того, какую конфигурацию брокера вы используете?Это было настроено вообще?

Брюс

0 голосов
/ 17 апреля 2013

Хотя это старый вопрос, отсутствует один очень очень важный совет:

  • Изучите количество тем и очередей, которые у вас есть.

ActiveMQ хранит темы подписки в отдельных темах.В частности, когда у вас большое количество разных тем, это приведет к перетаскиванию любого сервера.Подумайте об использовании селекторов JMS.

Я столкнулся с подобной ситуацией, когда у меня были тысячи сообщений рыночных данных в секунду.Когда я наивно сбрасывал каждое сообщение в специальный канал рыночного инструмента, сервер мог стоять примерно за час до того, как выплевывал сообщения об ошибках производителям сообщений.Я изменил дизайн, чтобы иметь ОДИН канал "MARKET_DATA", и затем я установил свойства заголовка для всех произведенных сообщений и установил селектор на стороне потребителя, чтобы выбрать только те сообщения, которые я хочу.Обратите внимание, что мой селектор выполнен в SQL-подобном синтаксисе и работает на сервере, хотя ... (да, давайте пропустим разбивку рекламы CEP) ...

0 голосов
/ 01 ноября 2010

Мы не используем ActiveMQ, но мы столкнулись с похожими проблемами, мы обнаружили, что проблемы были связаны с серверной обработкой, а не со стороной Java.Здесь может быть несколько проблем:

  1. Программа, обрабатывающая сообщения из очереди, может быть медленной (например, CICS на мэйнфрейме), она может не справиться с сообщениями, отправленными в очередь,Одним из возможных решений для этого является увеличение вычислительной мощности (или оптимизация внутреннего кода, который обрабатывает сообщения)
  2. Проверьте сообщения в очереди, иногда в очереди много неподтвержденных вредоносных сообщений, мыиспользуйте отдельную очередь для таких сообщений.

Было бы приятно узнать ответы на вопросы, заданные Карианной.

...