rabbitMQ-API 保证消息可靠性

导入依赖
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
# 应用名称
spring.application.name=rabbitmq
# 应用服务 WEB 访问端口
server.port=8080
spring.rabbitmq.host=192.168.1.137
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
@Configuration
public class RabbitMQConfig {
    public static final String EXCHANGE="boot-exchange";
    public static final String QUEUE="boot-queue";
    public static final String ROUTING_KEY="*.black.*";
    @Bean
    public Exchange bootExchange(){
        //channel.DeclareExchange
       return ExchangeBuilder.topicExchange(EXCHANGE).build();
    }
    @Bean
    public Queue bootQueue(){
        return QueueBuilder.durable(QUEUE).build();
    }
    @Bean
    public Binding bootBinding(Exchange bootExchange,Queue bootQueue){
        return BindingBuilder.bind(bootQueue).to(bootExchange).with(ROUTING_KEY).noargs();
    }
}
@Component
public class ConsumerListener {

    @RabbitListener(queues = RabbitMQConfig.QUEUE)
    //必须先写配置文件 关闭自动提交ack  msg 是string类型 也可以方其他对象  例如Person
    public void consume(String msg, Channel channel, Message message) throws IOException {
        System.out.println("队列消息为"+msg);
        String correlationId = message.getMessageProperties().getCorrelationId();
        System.out.println("唯一标识为"+correlationId);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(deliveryTag,false);
    }
}
@SpringBootTest
class RabbitmqApplicationTests {

    @Autowired
    RabbitTemplate rabbitTemplate;

    /*普通发送消息*/
    @Test
    void contextLoads() {
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE,"big.black.dog","message");
        System.out.println("消息发送成功");
    }
    /*携带参数发送消息*/
    @Test
    void contextLoads1() {
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE,"big.black.dog","MessageProperties",new MessagePostProcessor(){
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setCorrelationId("123");
                return message;
            }
        });
        System.out.println("消息发送成功");
    }

}

 

 

 

 

public class Publisher {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_NAME="confirms";
    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
        ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }
    @Test
    public void publish() throws IOException, TimeoutException {
        //1获取连接对象
        Connection connection = Publisher.getConnection();
        //2构建Channel
        Channel channel = connection.createChannel();
        //3构建队列  durable 队列是否持久化  exclusive 如果为true 只允许一个消费者消费  autoDelete 队列长时间没有使用 自动删除
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        //4开启confirm
        channel.confirmSelect();
        //5是指confirms的异步回调
        String message="Hello World";
        channel.addConfirmListener(new ConfirmListener() {
            @Override
            public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                System.out.println("消息成功发送到交换机");
            }
            @Override
            public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                System.out.println("消息没有发送到交换机  尝试重试机制  或者保存到数据库做其他补偿操作");
            }
        });
        //6设置Return回调 确认消息是否路由到队列  如果没有路由到指定队列 则会执行该方法
        channel.addReturnListener(new ReturnListener() {
            @Override
            public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消息没有路由到指定队列时,会执行当前方法,做其他补偿措施");
            }
        });
        //7 设置消息持久化 deliveryMode(2) 代表持久化  设置为1 代表不会持久化
      AMQP.BasicProperties pros=new AMQP.BasicProperties()
              .builder()
              .deliveryMode(2)
              .build();
        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中
        channel.basicPublish("", QUEUE_NAME, true,pros, message.getBytes());
        System.out.println("消息发送成功");
        System.in.read();

    }
}

 

posted @ 2022-07-18 20:26  花心大萝卜li  阅读(47)  评论(0)    收藏  举报