使用StreamBridge实现RabbitMq 消息收发 && ack确认 && 延时消息

使用StreamBridge实现RabbitMq && 延时消息

Maven依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>

延时消息需要安装插件

下载地址:link
1.下载完成放到rabbitmq安装目录plugins下
2.执行命令启用插件
3.重启mq

rabbitmq-plugins enable rabbitmq_delayed_message_exchange  // 启用插件
//重启mq
rabbitmq-server stop
rabbitmq-server start

Exchanges -> add a new exchange -> type 出现x-delayed-message即安装成功

Exchanges -> add a new exchange -> type 出现x-delayed-message即安装成功

yml配置

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: xxxx
    password: xxxx

  function:
      # 与消费者对应(消费者方法名称)
      definition: ackMessage;normal;delay
    stream:
      rabbit:
        bindings:
          ackMessage-in-0:
            consumer:
              acknowledge-mode: manual  # manual手动确认 ,auto 自动确认
          delay-in-0:
            consumer:
              delayedExchange: true # 开启延时
          delay-out-0:
            producer:
              delayedExchange: true  # 开启延时

      bindings:
        delay-in-0:
          destination: delay.exchange.cloud  # mq对应交换机
          content-type: application/json
          consumer:
            acknowledge-mode: auto # manual手动确认 ,auto 自动确认
          group: delay-group	# 消息组
          binder: rabbit
        delay-out-0:
          destination: delay.exchange.cloud
          content-type: application/json
          group: delay-group
          binder: rabbit

        ackMessage-in-0:
          destination: ackMessage.exchange.cloud
          content-type: application/json
          consumer:
            acknowledge-mode: manual # manual手动确认 ,auto 自动确认
          group: ackMessage-group
          binder: rabbit
        ackMessage-out-0:
          destination: ackMessage.exchange.cloud
          content-type: application/json
          group: ackMessage-group
          binder: rabbit
        normal-in-0:
          destination: normal.exchange.cloud
          content-type: application/json
          consumer:
            acknowledge-mode: auto # manual手动确认 ,auto 自动确认
          group: normal-group
          binder: rabbit
        normal-out-0:
          destination: normal.exchange.cloud
          content-type: application/json
          group: normal-group
          binder: rabbit

接口controller


import com.alibaba.fastjson2.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * @Description: RabbitmqController
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/mq")
public class MqController {

	//消息发送者
    private final RabbitMqProducer rabbitMqProducer;

    /**
     * 发送普通消息Rabbitmq
     * bindingName 绑定队列名称
     * @param msg 消息内容
     */
    @GetMapping("/sendMessage/{msg}/{bindingName}")
    public R<Void> sendMessage(@PathVariable("msg") String msg, @PathVariable("bindingName") String bindingName) {
        log.info(bindingName + "发送消息: " + msg);
        rabbitMqProducer.sendMsg(msg, bindingName);
        return R.ok();
    }

    /**
     * 发送延迟消息
     *
     * @param message  消息实体
     * @return
     */
    @PostMapping("/sendDelayedMessage")
    public R<Void> sendDelayedMessage(@RequestBody Message message) {
        log.info(MqTExchangesEnum.delay + "发送延时消息: " + LocalDateTime.now() + "  " + message);
        rabbitMqProducer.sendDelayMsg(JSON.toJSONString(message), message.getBindingName(), message.getSeconds());// 延迟时间(秒)
        return R.ok();
    }
}

发送者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * RabbitMq消息生产者
 */
@Component
public class RabbitMqProducer {

    @Autowired
    private StreamBridge streamBridge;

    /**
     * @Description RabbitMq消息生产者
     * @Param msg 消息内容
     * @Param bindingName  exchange绑定queue名称
     **/
    public void sendMsg(String msg, String bindingName) {
        // 构建消息对象
        Messaging messaging = new Messaging().setMsgId(UUID.randomUUID().toString()).setMsgText(msg);
        Message<Messaging> message = MessageBuilder.withPayload(messaging).build();
        streamBridge.send(bindingName, message);
    }

    /**
     * 发送延迟消息
     *
     * @param msg
     * @param bindingName
     * @param seconds
     */
    public void sendDelayMsg(String msg, String bindingName, Integer seconds) {
        // 构建消息对象
        Messaging messaging = new Messaging().setMsgId(UUID.randomUUID().toString()).setMsgText(msg);
        Message<Messaging> message = MessageBuilder.withPayload(messaging).setHeader("x-delay", seconds * 1000).build();
        streamBridge.send(bindingName, message);
    }
}

消费者

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

import java.time.LocalDateTime;
import java.util.function.Consumer;


/**
 * RabbitMq消息消费者
 */
@Component
@Slf4j
public class RabbitMqConsumer {

    /**
     * mq接收ackMessage消息/手动ack确认
     * @methodName 配置文件对应
     **/
    @Bean
    Consumer<Message<Messaging>> ackMessage() {
        log.info("ackMessage-初始化订阅");
        return obj -> {
            Channel channel = obj.getHeaders().get(AmqpHeaders.CHANNEL, Channel.class);
            Long deliveryTag = obj.getHeaders().get(AmqpHeaders.DELIVERY_TAG, Long.class);
            try {
                log.info("ackMessage-消息接收成功:" + obj.getPayload());
                //业务逻辑处理
                //ack确认
                channel.basicAck(deliveryTag, false);
            } catch (Exception e) {
                //重新回队列-true则重新入队列,否则丢弃或者进入死信队列。
//                    channel.basicReject(deliveryTag, true);
                log.error(e.getMessage());
            }

        };
    }

    /**
     * mq接收normal消息
     **/
    @Bean
    Consumer<Messaging> normal() {
        log.info("normal-初始化订阅");
        return obj -> {
            log.info("normal-消息接收成功:" + obj);
            //业务逻辑处理
        };
    }


    /**
     * mq接收延时消息
     * Messaging 发送实体消息接收实体消息
     **/
    @Bean
    Consumer<Message<Messaging>> delay() {
        log.info("delay-初始化订阅");
        return obj -> {
            Messaging payload = obj.getPayload();
            log.info("delay-消息接收成功:" + LocalDateTime.now() + "  " + payload);
            //业务逻辑处理
        };
    }
}

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单的 Spring Boot 整合 RabbitMQ使用 RabbitTemplate 实现 ACK 消息确认的示例: 首先,在 pom.xml 文件中添加 RabbitMQ 和 Spring Boot 的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 然后,在 application.yml 文件中配置 RabbitMQ 的连接信息: ```yaml spring: rabbitmq: host: localhost port: 5672 username: guest password: guest ``` 接下来,在代码中使用 RabbitTemplate 发送消息,并实现 ACK 消息确认: ```java import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.support.CorrelationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MessageSender implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String exchange, String routingKey, Object message) { rabbitTemplate.setConfirmCallback(this); rabbitTemplate.setReturnCallback(this); CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); rabbitTemplate.convertAndSend(exchange, routingKey, message, correlationData); } @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { if (ack) { System.out.println("消息发送成功:" + correlationData); } else { System.out.println("消息发送失败:" + cause); } } @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { System.out.println("消息发送失败:" + message); } } ``` 以上代码中,MessageSender 类是一个消息发送者,通过 sendMessage 方法发送消息使用 CorrelationData 存储消息的唯一标识,用于 ACK 消息确认。在发送消息前,需要设置 ConfirmCallback 和 ReturnCallback,以便在消息成功或失败时得到通知。在实现 ConfirmCallback 和 ReturnCallback 接口的方法中,打印出消息的成功或失败信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值