如何使用ActiveMQ和Spring Integration JMS在多个组中一次接收消息?

时间:2017-02-10 21:05:58

标签: jms spring-integration activemq messaging spring-jms

我正在尝试使用消息传递服务在创建系统中的用户时向其他服务发送消息。接收消息的服务是负载平衡的Spring Boot应用程序(在我们的例子中,是Kubernetes环境中的pod)。

Desired behavior, one recipient per group

我想:

  1. 每个服务中的每个pod都配置为接收消息。

  2. 每个服务中的一个(且只有一个)pod实际上接收每条消息。

  3. 这种方式可以通过多种服务接收消息。

  4. 因此,在图片中,“新用户”消息由Notification Service中的一个pod和Logging Service中的一个pod接收。

    我已经设置了ActiveMQ和Spring Integration来发送/接收消息,并使其成为a)队列(一个接收者)和b)一个主题(无论谁订阅接收它)。问题是:

    a)对于一个队列,一个收件人意味着通知会收到它,但Logging不会收到它(反之亦然)。

    Queue, one recipient

    b)有了一个主题,无论谁订阅,都意味着所有六个豆荚都会收到它。

    Topic, every subscriber receives

    我觉得我想要的是一个分组,比如“一个类型通知的收件人和一个LOGGING类型的收件人”,但我不确定如何实现它。看起来这可能是消息路由模式,但我想知道它是否可以完全使用Spring Integration实现。

    一些代码。发件人的配置:

    import org.apache.activemq.spring.ActiveMQConnectionFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jms.core.JmsTemplate;
    
    @Configuration
    public class MessagingConfig {      
        @Bean
        public ActiveMQConnectionFactory connectionFactory(){
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
            connectionFactory.setBrokerURL("tcp://myactivemq:61616");
            return connectionFactory;
        }
    
        @Bean
        public JmsTemplate jmsTemplate(){
            JmsTemplate template = new JmsTemplate();
            template.setConnectionFactory(connectionFactory());
            template.setDefaultDestinationName("user-dest");
            return template;
        }     
    }
    

    发送消息的服务(简化):

    @Service
    public class MessageSender {  
      private final JmsTemplate jmsTemplate;
    
      @Autowired
      public MessageSender(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
      }
    
      public void sendMessage(String userId) {    
        jmsTemplate.send(new MessageCreator() {
          @Override
          public Message createMessage(Session session) throws JMSException{
            return session.createTextMessage("NEW USER:" + userId);
          }
        });
      }
    }
    

    接收器的配置:

    import org.apache.activemq.spring.ActiveMQConnectionFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.jms.annotation.EnableJms;
    import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
    
    @Configuration
    @EnableJms
    public class ReceiverConfig {
    
      private ActiveMQConnectionFactory getConnectionFactory() {
          ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
          connectionFactory.setBrokerURL("tcp://myactivemq:61616");
          return connectionFactory;
      }
    
      @Bean
      public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
          DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
          factory.setConnectionFactory(getConnectionFactory());
          factory.setConcurrency("1-1");
          return factory;
      }
    }
    

    接收消息的服务。

    import javax.jms.JMSException;
    import javax.jms.TextMessage;
    import org.springframework.jms.annotation.JmsListener;
    
    @Service
    public class MessageReceiver {
    
      @JmsListener(destination = "user-dest")
      public void receiveMessage(final TextMessage message) throws JMSException {
        // Do something with message.getText()
      }
    }
    

    这是有效的,但就像一个队列,只有一个收件人。知道如何通过一个通知服务窗格和一个日志服务窗口接收到它吗?

1 个答案:

答案 0 :(得分:0)

FYI。我最终使用RabbitMQ,可能是因为我发现文档更容易。使用RabbitMQ,解决方案非常简单:

  • 将讯息发送至交易所
  • 创建队列并将队列绑定到交换机
    • 我使用了管理界面,但绑定也可以在代码中。
    • 从上面的示例中,我创建了两个队列,一个用于通知,一个用于记录。
  • 通知和日志记录服务会侦听各自的队列。

因此,用户服务向其Exchange发送一条消息,两个队列都会接收该消息,并且每个侦听服务只有一个pod获取该消息。正是我在寻找的东西。