如何修复后续请求的错误 "Only one ConfirmCallback is supported by each RabbitTemplate"
How to fix error "Only one ConfirmCallback is supported by each RabbitTemplate" on subsequent requests
我是 RabbitMQ 的新手,目前正在处理 RabbitMQ 发布确认我的 Web 应用程序中的确认。在每个新请求上,向 RabbitMQ 服务器发送消息以异步处理它,并启用确认以从 RMQ 服务器获得确认。
在本地尝试时,第一次请求没问题,但在后续请求中出现以下错误 "Only one ConfirmCallback is supported by each RabbitTemplate"。
经过一些研究,如果我在设置确认回调之前添加一个检查 (template.isConfirmListener()),则不会出现错误。但是,如果需要,我们如何覆盖不同请求的确认回调?这是预期的行为还是我在这里做错了什么?
环境:
- Spring 引导版本 2.1.7.RELEASE
- Java 8
请找到下面的代码。
控制器文件
package com.example.apis;
import java.util.UUID;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ProducerController {
@Autowired
private RabbitTemplate template;
private String exchange = "test";
private String routingKey = "test";
@GetMapping("/send")
@ResponseBody
public String sendRequestToRMQ() {
template.convertAndSend(exchange, routingKey, "Test Message", getCorrelationData());
template.setMandatory(true);
template.setConfirmCallback(new ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("Confirm Callback!");
System.out.println(correlationData.getId());
System.out.println(ack);
}
});
return "Success";
}
@GetMapping("/send1")
@ResponseBody
public String sendRequestToRMQ2() {
template.convertAndSend(exchange, routingKey, "Test Message", getCorrelationData());
template.setMandatory(true);
template.setConfirmCallback(new ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("Confirm Callback!");
System.out.println(correlationData.getId());
System.out.println(ack);
}
});
return "Success";
}
private CorrelationData getCorrelationData() {
return new CorrelationData(UUID.randomUUID().toString());
}
}
配置文件
package com.example.conf;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConnectionConfig {
@Value("${spring.rabbitmq.host:localhost}")
public String host;
@Value("${spring.rabbitmq.port:5672}")
public int port;
@Value("${spring.rabbitmq.username:guest}")
public String username;
@Value("${spring.rabbitmq.password:guest}")
public String password;
@Value("${spring.rabbitmq.virtual-host:/}")
public String virtualHost;
@Bean
public ConnectionFactory getConnectionFactory(){
CachingConnectionFactory factory=new CachingConnectionFactory();
factory.setHost(host);
factory.setPort(port);
factory.setUsername(username);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setPublisherConfirms(true);
factory.setPublisherReturns(true);
return factory;
}
}
请帮助我。谢谢
不,这是预期的行为:只能将一个 ConfirmCallback
注入 RabbitTemplate
。您需要考虑只在 @PostConstrcut
中的某处执行一次,但不是对每个请求都执行一次。当然,您可能需要修改您的逻辑,因为现在 ConfirmCallback
将被所有发起到 RabbitTemplate
.
的请求共享
您可能会考虑在常用 ConfirmCallback
中使用一些智能逻辑,以根据 getCorrelationData()
将请求存储在地图中,并从回调方法中恢复该条目。
我是 RabbitMQ 的新手,目前正在处理 RabbitMQ 发布确认我的 Web 应用程序中的确认。在每个新请求上,向 RabbitMQ 服务器发送消息以异步处理它,并启用确认以从 RMQ 服务器获得确认。
在本地尝试时,第一次请求没问题,但在后续请求中出现以下错误 "Only one ConfirmCallback is supported by each RabbitTemplate"。
经过一些研究,如果我在设置确认回调之前添加一个检查 (template.isConfirmListener()),则不会出现错误。但是,如果需要,我们如何覆盖不同请求的确认回调?这是预期的行为还是我在这里做错了什么?
环境:
- Spring 引导版本 2.1.7.RELEASE
- Java 8
请找到下面的代码。
控制器文件
package com.example.apis;
import java.util.UUID;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ProducerController {
@Autowired
private RabbitTemplate template;
private String exchange = "test";
private String routingKey = "test";
@GetMapping("/send")
@ResponseBody
public String sendRequestToRMQ() {
template.convertAndSend(exchange, routingKey, "Test Message", getCorrelationData());
template.setMandatory(true);
template.setConfirmCallback(new ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("Confirm Callback!");
System.out.println(correlationData.getId());
System.out.println(ack);
}
});
return "Success";
}
@GetMapping("/send1")
@ResponseBody
public String sendRequestToRMQ2() {
template.convertAndSend(exchange, routingKey, "Test Message", getCorrelationData());
template.setMandatory(true);
template.setConfirmCallback(new ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("Confirm Callback!");
System.out.println(correlationData.getId());
System.out.println(ack);
}
});
return "Success";
}
private CorrelationData getCorrelationData() {
return new CorrelationData(UUID.randomUUID().toString());
}
}
配置文件
package com.example.conf;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConnectionConfig {
@Value("${spring.rabbitmq.host:localhost}")
public String host;
@Value("${spring.rabbitmq.port:5672}")
public int port;
@Value("${spring.rabbitmq.username:guest}")
public String username;
@Value("${spring.rabbitmq.password:guest}")
public String password;
@Value("${spring.rabbitmq.virtual-host:/}")
public String virtualHost;
@Bean
public ConnectionFactory getConnectionFactory(){
CachingConnectionFactory factory=new CachingConnectionFactory();
factory.setHost(host);
factory.setPort(port);
factory.setUsername(username);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setPublisherConfirms(true);
factory.setPublisherReturns(true);
return factory;
}
}
请帮助我。谢谢
不,这是预期的行为:只能将一个 ConfirmCallback
注入 RabbitTemplate
。您需要考虑只在 @PostConstrcut
中的某处执行一次,但不是对每个请求都执行一次。当然,您可能需要修改您的逻辑,因为现在 ConfirmCallback
将被所有发起到 RabbitTemplate
.
您可能会考虑在常用 ConfirmCallback
中使用一些智能逻辑,以根据 getCorrelationData()
将请求存储在地图中,并从回调方法中恢复该条目。