rabbitMQ

生产者:

@Configuration
public class RabbitFanoutConfig {

     * 声明短信队列
    @Bean(name = "smsQueu")
    public Queue queue(){
        return new Queue("sms-queue");
    }


     * 声明交换机 fanoutExchange
    @Bean(name = "fanoutExchange")
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("sending-exchange");
    }


     * 将sms-queue绑定到了交换机上
    @Bean
    Binding bindSmsQueueToExchange(@Qualifier("fanoutExchange") FanoutExchange     fanoutExchange,@Qualifier("smsQueu")Queue queue){
       return BindingBuilder.bind(queue).to(fanoutExchange);
    }

         * routing模式  路由模式(可以给单个队列发送,也可以同时给多个队列发送)
       @Bean
    Binding bindEmailAllToDirectExchange(@Qualifier("directExchange")DirectExchange directExchange,@Qualifier("emailQueue")Queue queue){
        return  BindingBuilder.bind(queue).to(directExchange).with("routingKey:规则");
    }

     * 通配符模式可以简化routing模式,当我们同时要给队列发送时,routing需要绑定多个路由,比较繁琐
     * 使用topic 可以 简化路由:
     *    使用* 代表一个字符
     *    使用# 代表0个或多个字符
    @Bean
    Binding bindSmsToTopicExchange(@Qualifier("topicExchange")TopicExchange topicExchange,@Qualifier("smsTopicQueue")Queue queue){
     return    BindingBuilder.bind(queue).to(topicExchange).with("#.sms");
    }

    @Bean
    Binding bindEmailToTopicExchange(@Qualifier("topicExchange")TopicExchange topicExchange,@Qualifier("emailTopicQueue")Queue queue){
        return    BindingBuilder.bind(queue).to(topicExchange).with("email.#");
    }
    延迟队列
    @Bean(name = "deadqueue")
    public Queue deadQueue(){
        /**
         1、name: 队列的名称;
         2、durable: 是否持久化;
         3、exclusive: 是否独享、排外的;
         4、autoDelete: 是否自动删除;
         5.arguments:队列的其他属性参数,
         (1)x-message-ttl:消息的过期时间,单位:毫秒;
         (2)x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;
         (3)x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;
         (4)x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;
         (5)x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;
         (6)x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中; dlx
         (7)x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值
         (8)x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)
         (9)x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;
         (10)x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;
         (11)x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。
         */
        //配置死信队列的配置
        Map map = new HashMap<>();
        //1.设置当前消息过期后,发送到指定的正常交换机中
        map.put("x-dead-letter-exchange","normal-topic");
        //2.设置转发到正常队列时的路由键
        map.put("x-dead-letter-routing-key","normal");
        //3.设置队列的存活时长,一般发送的时候配置
        //map.put("x-message-ttl",10000);
        return new Queue("dead-queue",true,false,false,map);
    }
}

生产者确认机制,需要再配置文件开启确认机制

    #开启确认机制 消息发送到交换机的确认
    spring.rabbitmq.publisher-confirms: true
    #开启 交换机转发到队列的确认
    spring.rabbitmq.publisher-returns: true
    #将自动确认更改为手动确认
    listener.simple.acknowledge-mode: manual
@Configuration
public class ConfirmCallBackConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {

    @Autowired
    RabbitTemplate rabbitTemplate;

    //实例化该类对象时,首先执行的方法,修改模板类,设置确认的回调方法
    @PostConstruct
    public void  rabbitTemplate(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    @Override
    /**
     * 消息发送到交换机的确认,如果没有发送成功,则进行数据的持久化,或者重新发送
     */
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        System.out.println("Confirm: " + correlationData + ", ack=" + b
                + (s == null ? "" : (", cause: " + s)));
    }

    /**
     * 交换机转发到队列的确认
     * @param message  信息
     * @param replyCode code码
     * @param replyText 返回信息
     * @param exchange 交换机名称
     * @param routingKey 路由键
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("信息主体为:"+message);
        System.out.println("返回的code码为:"+replyCode);
        System.out.println("返回的文本为:"+replyText);
        System.out.println("交换机的名称:"+exchange);
        System.out.println("路由键:"+routingKey);
    }
}

消费者:

@Component
public class RabbitListen {

     * 1.RabbitListener 监听队列的名称。
     * 2.没有返回值 默认为void
     * 3.当消费者消费 消息时发生报错,则该条消息被rabbit认为没有正确消费,队列种的消息不会被清除,一直尝试消费,直到成功为止
      * 消息的接受的确认机制 ,有自动的ack回复,变为手动的ack
    @RabbitListener(queues = "队列名称")
    public void listentopSms(String  msg, Channel channel, Message message) throws             IOException {
        try {
            System.out.println("消息主体为:========="+msg);
        System.out.println("消息的唯一标识:========="+message.getMessageProperties().getMessageId());
        System.out.println("消息的消费顺序:========="+message.getMessageProperties().getDeliveryTag());
            //使用channel 确认 消息是否被正确消费 1.消息的唯一标识。2.是否时批量处理
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }catch (Exception e){
            System.out.println("消息没有被正确消费");
        }
}

controller

@RequestMapping("/send")
@RestController
public class SendController {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @RequestMapping("/sendToSMS/{msg}")
    public String sendToSMS(@PathVariable("msg")String msg){

        rabbitTemplate.convertAndSend("publish-Top-exchange", "sms", msg, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
                return message;
            }
        });

        return "success";
    }

    @RequestMapping("/sendLazy/{msg}")
    public String sendLazy(@PathVariable("msg")String msg){
        //设置额外的参数
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(UUID.randomUUID().toString());

         * 4.MessagePostProcessor 消息的前置增强
         * 5.correlationData 携带的额外的参数

        rabbitTemplate.convertAndSend("交换机名称","路由信息",消息主体, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //从message中获取到message的属性
                MessageProperties messageProperties = message.getMessageProperties();
                //设置message信息的唯一标识
                messageProperties.setMessageId(UUID.randomUUID().toString());
                //设置message信息的存活时长
                messageProperties.setExpiration("10000");
                return message;
            }
        },correlationData);
        return "success";
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值