使用rabbitMQ的Spring amqp延迟消息传递
在Spring AMQP/Rabbit MQ中,我正在努力寻找计划/延迟消息的方法,并在这里找到了解决方案 关于Spring AMQP/Rabbit MQ,它无法接收任何消息 我的资料来源如下:使用rabbitMQ的Spring amqp延迟消息传递,spring,rabbitmq,amqp,Spring,Rabbitmq,Amqp,在Spring AMQP/Rabbit MQ中,我正在努力寻找计划/延迟消息的方法,并在这里找到了解决方案 关于Spring AMQP/Rabbit MQ,它无法接收任何消息 我的资料来源如下: @Configuration public class AmqpConfig { @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFa
@Configuration
public class AmqpConfig {
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("172.16.101.14:5672");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setPublisherConfirms(true);
return connectionFactory;
}
@Bean
@Scope("prototype")
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
@Bean
CustomExchange delayExchange() {
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-delayed-type", "direct");
return new CustomExchange("my-exchange", "x-delayed-message", true, false, args);
}
@Bean
public Queue queue() {
return new Queue("spring-boot-queue", true);
}
@Bean
Binding binding(Queue queue, Exchange delayExchange) {
return BindingBuilder.bind(queue).to(delayExchange).with("spring-boot-queue").noargs();
}
@Bean
public SimpleMessageListenerContainer messageContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
container.setQueues(queue());
container.setExposeListenerChannel(true);
container.setMaxConcurrentConsumers(1);
container.setConcurrentConsumers(1);
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setMessageListener(new ChannelAwareMessageListener() {
public void onMessage(Message message, Channel channel) throws Exception {
byte[] body = message.getBody();
System.err.println("receive msg : " + new String(body));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费
}
});
return container;
}
}
@Component
public class Send implements RabbitTemplate.ConfirmCallback{
private RabbitTemplate rabbitTemplate;
@Autowired
public Send(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
this.rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setMandatory(true);
}
public void sendMsg(String content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend("my-exchange", "", content, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setHeader("x-delay", 6000);
return message;
}
},correlationId);
System.err.println("delay message send ................");
}
/**
* 回调
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.err.println(" callback id :" + correlationData);
if (ack) {
System.err.println("ok");
} else {
System.err.println("fail:" + cause);
}
}
}
@配置
公共类AmqpConfig{
@豆子
公共连接工厂ConnectionFactory(){
CachingConnectionFactory connectionFactory=新的CachingConnectionFactory();
connectionFactory.setAddresses(“172.16.101.14:5672”);
connectionFactory.setUsername(“管理员”);
connectionFactory.setPassword(“管理员”);
connectionFactory.SetPublisherConfigrms(true);
返回连接工厂;
}
@豆子
@范围(“原型”)
公共rabbitmplate rabbitmplate(){
RabbitTemplate=新的RabbitTemplate(connectionFactory());
返回模板;
}
@豆子
CustomExchange延迟交换(){
Map args=new HashMap();
参数put(“x延迟类型”、“直接”);
返回新的CustomExchange(“我的exchange”、“x-delayed-message”、真、假、args);
}
@豆子
公用队列(){
返回新队列(“spring引导队列”,true);
}
@豆子
绑定绑定(队列、交换延迟交换){
返回BindingBuilder.bind(queue).to(delayExchange).with(“spring引导队列”).noargs();
}
@豆子
公共SimpleMessageListenerContainer messageContainer(){
SimpleMessageListenerContainer容器=新的SimpleMessageListenerContainer(connectionFactory());
setQueues(queue());
container.setExposeListenerChannel(true);
container.setMaxConcurrentConsumers(1);
容器。setConcurrentConsumers(1);
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setMessageListener(新ChannelAwareMessageListener(){
public void onMessage(消息消息,通道)引发异常{
byte[]body=message.getBody();
System.err.println(“接收消息:+新字符串(正文));
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false)//确认消息成功消费
}
});
返回容器;
}
}
@组成部分
公共类Send实现RabbitTemplate.ConfirmCallback{
私人兔样板兔样板;
@自动连线
公共发送(rabbitmplate rabbitmplate){
this.rabbitmplate=rabbitmplate;
this.rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setMandatory(true);
}
public void sendMsg(字符串内容){
CorrelationData correlationId=新的CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(“我的交换”,内容,新消息后处理器(){
@凌驾
公共消息后处理消息(消息消息)引发AmqpException{
message.getMessageProperties().setHeader(“x-delay”,6000);
返回消息;
}
},correlationId);
System.err.println(“延迟消息发送”);
}
/**
* 回调
*/
@凌驾
公共无效确认(CorrelationData CorrelationData,布尔值确认,字符串原因){
System.err.println(“回调id:+correlationData”);
如果(ack){
系统错误打印项次(“正常”);
}否则{
系统错误打印项次(“失败:+原因);
}
}
}
有没有人可以帮忙
谢谢大家。延迟消息与Spring amqp无关,它是一个与您的代码一起驻留的库,因此该库不能保存任何这样的消息。您可以尝试两种方法: 旧方法: 在每个消息/队列(策略)中设置TTL(生存时间)头,然后引入DLQ来处理它。一旦ttl过期,您的消息将从DLQ移动到主队列,以便您的侦听器可以处理它 最新方法: 最近RabbitMQ推出了RabbitMQ延迟消息插件,使用它您可以实现与RabbitMQ-3.5.8相同的插件支持 您可以声明类型为x-delayed-message的交换,然后使用自定义标头x-delay发布消息,以毫秒表示消息的延迟时间。消息将在x延迟毫秒后传递到相应的队列 详细信息: 要使用延迟消息功能,请声明类型为x-delayed-message的exchange:
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-delayed-type", "direct");
channel.exchangeDeclare("my-exchange", "x-delayed-message", true, false, args);
Map args=newhashmap();
参数put(“x延迟类型”、“直接”);
channel.ExchangeClare(“我的交换”、“x-delayed-message”、真、假、args);
请注意,我们传递了一个名为x-delayed-type的额外头,更多信息请参见Routing部分
声明exchange后,我们可以发布消息,提供一个标题,告诉插件消息延迟多长时间:
byte[] messageBodyBytes = "delayed payload".getBytes("UTF-8");
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("x-delay", 5000);
AMQP.BasicProperties.Builder props = new AMQP.BasicProperties.Builder().headers(headers);
channel.basicPublish("my-exchange", "", props.build(), messageBodyBytes);
byte[] messageBodyBytes2 = "more delayed payload".getBytes("UTF-8");
Map<String, Object> headers2 = new HashMap<String, Object>();
headers2.put("x-delay", 1000);
AMQP.BasicProperties.Builder props2 = new AMQP.BasicProperties.Builder().headers(headers2);
channel.basicPublish("my-exchange", "", props2.build(), messageBodyBytes2);
byte[]messageBodyBytes=“延迟的有效负载”。getBytes(“UTF-8”);
Map headers=newhashmap();
标题。放置(“x延迟”,5000);
AMQP.BasicProperties.Builder props=新的AMQP.BasicProperties.Builder().headers(headers);
channel.basicPublish(“我的交换”,props.build(),messageBodyBytes);
byte[]messageBodyBytes2=“更多延迟的有效负载”。getBytes(“UTF-8”);
Map headers2=新的HashMap();
头2.放置(“x延迟”,1000);
AMQP.BasicProperties.Builder props2=新的AMQP.BasicProperties.Builder().headers(headers2);
channel.basicPublish(“我的交换”,props2.build(),messageBodyBytes2);
在上面的示例中,我们发布了两条消息,用x-delay头指定延迟时间。在本例中,插件将首先向队列发送正文为“more delayed payload”的消息,然后发送正文为“delayed payload”的消息