RabbitMQ实战篇:消息确认之生产者确认

生产者把消息发送到exchange 确认。通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中 implements RabbitTemplate.ConfirmCallback

看一下代码实现:

配置类:

package com.lwl.rabbitmq.config;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

public class RabbitConfig {
    
    @Value("${spring.rabbitmq.host}")
    private String addresses;
    
    @Value("${spring.rabbitmq.port}")
    private String port;

    @Value("${spring.rabbitmq.username}")
    private String username;

    @Value("${spring.rabbitmq.password}")
    private String password;

    @Value("${spring.rabbitmq.virtual-host}")
    private String virtualHost;

    @Value("${spring.rabbitmq.publisher-confirms}")
    private boolean publisherConfirms;
    
    @Value("${spring.rabbitmq.publisher-returns}")
    private boolean publisherReturns;
    
    @Bean
    public ConnectionFactory connectionFactory() {

        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(addresses+":"+port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        /** 如果要进行消息回调,则这里必须要设置为true */
        connectionFactory.setPublisherConfirms(publisherConfirms);
        connectionFactory.setPublisherReturns(publisherReturns);
        return connectionFactory;
    }
    
    @Bean
    /** 因为要设置回调类,所以应是prototype类型,如果是singleton类型,则回调类为最后一次设置 */
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplatenew() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        return template;
    }

}
package com.lwl.rabbitmq.config;


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.lwl.rabbitmq.constant.Constants;

/**
 * 发送消息 配置发送消息的队列queue
 * @author lwl
 * @create 2018年8月10日 下午2:37:38
 * @version 1.0
 */
@Configuration
public class SendMessageConfig {

    @Bean
    public Queue topicQueue() {
    	return new Queue(Constants.TOPIC_QUEUE);
    }
    
    @Bean
    TopicExchange exchange() {
        return new TopicExchange(Constants.TOPIC_NAME);
    }
    
    /**
     * 使用主题交换机, 
     *  	将队列Constants.TOPIC_QUEUE与exchange绑定,binding_key为topic.queue.key,就是完全匹配
     * @param topicQueue
     * @param exchange
     * @return
     * @author lwl
     * @create 2019年6月14日 上午10:51:21
     */
    @Bean
    Binding bindingExchangeMessage(Queue topicQueue, TopicExchange  exchange) {
        return BindingBuilder.bind(topicQueue).to(exchange).with(Constants.ROUTING_KEY);
    }
    
    
    
}

配置文件:


# 配置rabbitmq
spring: 
      rabbitmq:
        host: 192.168.3.66
        port: 5672
        username: lwl
        password: 123456
        publisher-confirms: true
        publisher-returns: true
        virtual-host: /

生产者:

package com.lwl.rabbitmq.producer;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;

import com.lwl.rabbitmq.constant.Constants;

/**
 * 生成者
 * @author lwl
 * @create 2019年6月14日 上午10:56:41
 * @version 1.0
 */
@Component
public class AckProducer implements RabbitTemplate.ConfirmCallback , RabbitTemplate.ReturnCallback{

	@Autowired
    private RabbitTemplate rabbitTemplatenew;

    /**
     * 使用主题交换机
     * @param message
     * @author lwl
     * @create 2019年6月14日 上午10:54:54
     */
    public void send(Object message){
    	rabbitTemplatenew.setConfirmCallback(this);
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());  
        System.out.println();
        System.out.println("callbackSender UUID: " + correlationData.getId());  
        System.out.println();
        this.rabbitTemplatenew.convertAndSend(Constants.TOPIC_NAME,Constants.ROUTING_KEY, message, correlationData);  
    }
    /**
     * 
     * 通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中
     * @param correlationData
     * @param ack
     * @param cause
     * @author lwl
     * @create 2019年6月17日 上午9:46:59
     */
	@Override
	public void confirm(CorrelationData correlationData, boolean ack, String cause) {
		//
		System.out.println();
		System.out.println();
		 System.out.println("callbakck confirm: " + correlationData.getId());
		 System.out.println();
		 System.out.println();
	}
	
	/**
	 * 通过实现 ReturnCallback 接口,启动消息失败返回,比如路由不到队列时触发回调
	 * @param message
	 * @param replyCode
	 * @param replyText
	 * @param exchange
	 * @param routingKey
	 * @author lwl
	 * @create 2019年6月17日 上午10:01:47
	 */
	@Override
	public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
		System.out.println("消息主体 message : "+message);
        System.out.println("消息主体 message : "+replyCode);
        System.out.println("描述:"+replyText);
        System.out.println("消息使用的交换器 exchange : "+exchange);
        System.out.println("消息使用的路由键 routing : "+routingKey);		
	}
    
    
}

消费者:

package com.lwl.rabbitmq.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import com.lwl.rabbitmq.constant.Constants;

/**
 * 消费者
 * @author lwl
 * @create 2019年6月14日 上午10:57:11
 * @version 1.0
 */
@Component
@RabbitListener(queues = Constants.TOPIC_QUEUE)
public class TopicAckConsumer {

	@RabbitHandler
    public void process(String hello) {
		
		System.out.println();
		System.out.println("-----------------------客户端  3  收到数据 -----------------------");
        System.out.println(Constants.TOPIC_QUEUE+ " --> Receiver3  : " + hello);
        System.out.println();
    }
	
}

测试用例:

package com.lwl.rabbitmq;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import com.lwl.rabbitmq.producer.AckProducer;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes={RabbitmqAckApplication.class})
@WebAppConfiguration
public class RabbitmqAckApplicationTests {

	@Resource
	private AckProducer ackProducer;
	
	@Test
	public void send() {
		String message = " message with ack ";
		ackProducer.send(message );
		
	}

}

结果分析:


callbackSender UUID: 2c3a2573-fd21-4160-bb5d-f8f6cbe97cc3

 
callbakck confirm: 2c3a2573-fd21-4160-bb5d-f8f6cbe97cc3

消息发送到exchange之后,返回的uuid 和发送的uuid 是一样的

 

你可能感兴趣的:(rabbitmq,RabbitMQ实战)