Как spring jms распределяет сообщения среди надежных слушателей темы?

необработанный JMS-код:

TopicSubscriber durSubscriber1 = receiverSession.createDurableSubscriber(topic,"subscription_1");
durSubscriber1.setMessageListener(new MessageListener() {
    @Override
    public void onMessage(Message message) {

        RMQTextMessage rmqTextMessage = ((RMQTextMessage) message);
        try {
            System.out.println("sub_1:" + rmqTextMessage.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }

    }
});


TopicSubscriber durSubscriber2 = receiverSession.createDurableSubscriber(topic,"subscription_2");
    durSubscriber2.setMessageListener(new MessageListener() {
        @Override
        public void onMessage(Message message) {

            RMQTextMessage rmqTextMessage = ((RMQTextMessage) message);
            try {
                System.out.println("sub_2:" + rmqTextMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }

        }
});

Когда я использую следующий код, каждый слушатель получает все сообщения. Если я использую то же имя подписки - приложение не запускается.

С другой стороны я написал код, который использует Spring JMS:

конфигурация:

@Bean
public JmsListenerContainerFactory<?> myFactory(DefaultJmsListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some of Boot's default if necessary.
    factory.setPubSubDomain(true);
    factory.setSubscriptionDurable(true);
    return factory;
}

слушатели:

@JmsListener(destination = "my_topic_new", containerFactory = "myFactory")
public void receiveTopic(Email email) {
    System.out.println("list_1:" + email);
}

@JmsListener(destination = "my_topic_new", containerFactory = "myFactory")
public void receiveTopicDup(Email email) {
    System.out.println("list_2:" + email);
}

В этом случае оба слушателя разделяют сообщения. Я имею в виду, что если производитель отправит 10 сообщений, то слушатель_1 получит N сообщений, а слушатель_2 получит M сообщений.
M+N=10

Пожалуйста, объясните разницу в 2 фрагментах кода. Можете ли вы предоставить соответствующий код jms для версии spring-jms?


person gstackoverflow    schedule 23.08.2017    source источник


Ответы (1)


Это связано с тем, как JMS-клиент кролика сопоставляет JMS с собственным AMQP. Вы должны дать каждому слушателю имя подписки; в противном случае они будут конкурировать за сообщения в одной очереди.

@JmsListener(destination = "my_topic_new", containerFactory = "myFactory", subscription = "foo")
public void receiveTopic(String email) {
    System.out.println("list_1:" + email);
}

@JmsListener(destination = "my_topic_new", containerFactory = "myFactory", subscription = "bar")
public void receiveTopicDup(String email) {
    System.out.println("list_2:" + email);
}

Это необходимо только для устойчивых подписок.

person Gary Russell    schedule 23.08.2017