提问人:CoderJammer 提问时间:10/17/2023 最后编辑:CoderJammer 更新时间:10/17/2023 访问量:58
在 ActiveMQ Artemis 控制台上看不到 Pub/Sub 消息
Cannot see Pub/Sub message on ActiveMQ Artemis console
问:
我正在使用 Felipe Gutierrez (2017) 的 Spring Boot Messaging 一书学习 JMS。
它说明了有关消息驱动编程的几种模式,但是,到达代理时,它解释了使用 Apache ActiveMQ 的 Java / Spring Boot 消息传递。
它说解释的代码将与任何其他代理一起使用,所以我安装了 ActiveMQ Artemis。
我有一个非常简单的源代码,配置:
@Configuration
public class JmsConfig {
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_class_"); // This value can be anything, it will save the JSON class name and it must be the same for sender/receiver
return converter;
}
}
a Sender 类:
@Component
public class Sender {
private final JmsTemplate jmsTemplate;
public Sender(JmsTemplate jmsTemplate){
this.jmsTemplate = jmsTemplate;
}
public void sendMessage(String destination, String message){
this.jmsTemplate.convertAndSend("test-destination", message);
}
}
和一个接收器:
....
@JmsListener(destination = "test-destinaton")
public void consumeTopicOne(String message) {
log.info("Received Message Queue/Topic1: " + message);
}
....
文件如下:application.properties
spring.artemis.mode=native
spring.artemis.embedded.enabled=false
spring.artemis.broker-url=tcp://localhost:61616
spring.artemis.user=admin
spring.artemis.password=admin
spring.jms.pub-sub-domain=false
注意:主类没有注解。@EnableJms
现在,我设法使用“点对点”模式(队列)发送消息,并在我的控制台中看到它,只要我注释掉接收器:
如果我单击消息计数,我可以看到文本(还有其他选项)。但是,如果我尝试切换到 Publisher/Subscriber 方法,请设置以下属性(根据本书):
spring.jms.pub-sub-domain=true
应用程序运行良好,消息将被发送和接收,但我无法在控制台上看到它!即使我注释掉了接收者(就像我对队列所做的那样),我仍然看不到发送的消息。
因此,谈到队列:为什么我只有在尚未收到消息时才看到消息?拥有已发送消息的历史记录可能很有用。
谈到 Pub/Sub:为什么无论消息是否被消费,我都看不到任何内容?
关于这本书..也许我必须改变它?
感谢您的所有回复。
我查看了 @justin-bertram 发布给我的讨论,我读到:
由于您正在向 JMS 主题发送消息,因此您将受到主题 发布/订阅语义。发布/订阅语义决定 消息仅放置在有效的订阅中。当您的 订阅者处于脱机状态,它在代理上没有有效的订阅 接收消息,因此它将错过发送给它的消息 当它处于离线状态时。
您可以使用持久订阅者在 订阅者处于离线状态
这不是有效的订阅吗:
@JmsListener(destination = "test-destinaton")
public void consumeTopicOne(String message) {
log.info("Received Message Queue/Topic1: " + message);
}
这个例子直接取自这本书,我发现其他的例子非常清楚,与我的非常相似,例如这里。
我将尝试使用客户端服务器架构,但似乎很奇怪,我不能将(例如目的)发布者和订阅者放在同一个项目中。
答:
该属性配置 JmsTemplate 和 JmsMessageListenerContainer 的工作方式,请参阅文档。spring.jms.pub-sub-domain
当目标是 JMS 队列时,因此可以随时接收任何已发送的消息。spring.jms.pub-sub-domain= false
当目标是 JMS 主题时,因此任何已发送的消息只能从当前订阅者接收。这就解释了为什么如果没有订阅者,您不会在控制台上看到这些消息。spring.jms.pub-sub-domain= true
当客户端接收到消息时,该消息将从服务器队列中删除。您可以使用非独占转移在收到邮件时将邮件的副本发送到另一个地址。
评论