带有Spring Boot,发送器和接收器的JMS位于同一软件包中:它有什么用?

时间:2018-10-04 19:47:01

标签: spring-boot jms activemq spring-jms

我正在学习JMS的Spring Boot,很高兴知道Spring Boot附带了Active MQ JMS代理。

我从spring page开始了如何实现这一目标的工作,它的魅力十足。现在我走得更远,创建了两个单独的spring boot应用程序,一个包含jms发送者代码,另一个包含接收者代码。

我尝试启动,但应用程序失败,因为两个应用程序都将同一端口用于JMS。我通过将其包含在一个应用程序中来解决了该问题

@Bean
      public BrokerService broker() throws Exception {
          final BrokerService broker = new BrokerService();
          broker.addConnector("tcp://localhost:61616");
          broker.addConnector("vm://localhost");
          broker.setPersistent(false);
          return broker;
      }

但是现在发件人正在成功发送消息,但收件人却无所事事。我搜索stackoverflow并查看thisthis。他们说:

  

如果要在生产中使用JMS,最好避免使用Spring Boot嵌入式JMS代理并将其单独托管。因此,对于PROD,首选3节点设置。

所以我的问题是: 1.将jms发送方和接收方放在同一应用程序上的目的是什么?有没有实际的例子 2.真的不可能使用Spring Boot嵌入式JMS来通信两个单独的应用程序。

1 个答案:

答案 0 :(得分:1)

如果请求突发发送,并且在服务器崩溃的情况下,您想在处理请求之前将它们保存在某个地方,则可能在同一应用程序中具有发送方和接收方。通常,您通常仍不会使用嵌入式代理。

嵌入式经纪人通常仅用于测试。

但是,您可以运行可从外部访问的嵌入式代理;只需像您一样触发BrokerService,但另一个应用程序需要连接tcp://...地址,而不是vm://...

编辑

App1:

@SpringBootApplication
@RestController
public class So52654109Application {

    public static void main(String[] args) {
        SpringApplication.run(So52654109Application.class, args);
    }

    @Bean
    public BrokerService broker() throws Exception {
        final BrokerService broker = new BrokerService();
        broker.addConnector("tcp://localhost:61616");
        broker.setPersistent(false);
        broker.start();
        return broker;
    }

    @Autowired
    private JmsTemplate template;

    @RequestMapping(path = "/foo/{id}")
    public String foo(@PathVariable String id) {
        template.convertAndSend("someQueue", id);
        return id + ": thank you for your request, we'll send an email to the address on file when complete";
    }

}

App2:

application.properties

spring.activemq.broker-url=tcp://localhost:61616

@SpringBootApplication
public class So526541091Application {

    public static void main(String[] args) {
        SpringApplication.run(So526541091Application.class, args);
    }

    @JmsListener(destination = "someQueue")
    public void process(String id) {
        System.out.println("Processing request for id");
    }

}

很明显,对于像这样的简单应用,您可能只是在第一个应用中运行了监听器。

但是,由于此配置没有消息的持久性,因此您可能会为生产应用程序使用外部代理(或启用持久性)。