我正在学习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并查看this和this。他们说:
如果要在生产中使用JMS,最好避免使用Spring Boot嵌入式JMS代理并将其单独托管。因此,对于PROD,首选3节点设置。
所以我的问题是: 1.将jms发送方和接收方放在同一应用程序上的目的是什么?有没有实际的例子 2.真的不可能使用Spring Boot嵌入式JMS来通信两个单独的应用程序。
答案 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");
}
}
很明显,对于像这样的简单应用,您可能只是在第一个应用中运行了监听器。
但是,由于此配置没有消息的持久性,因此您可能会为生产应用程序使用外部代理(或启用持久性)。