简单粗暴的rabbitMQ入门

注意:因为是写好了业务,后面总结记录的,所以直接贴代码,抹掉业务信息,对新手来说有一定的参考意义,如有错误,请见谅,知错不改哈哈哈哈哈哈哈哈哈哈。

一、自行百度,安装好rabbit所需要的环境,官网地址Messaging that just works — RabbitMQ

二、安装好环境后,引入依赖进项目。

三、创建消息队列配置,主要用于配置交换机、队列的绑定关系。

@Configuration
public class RabbitMqConfig {
/**
 * 消息队列所绑定的交换机
 **/
@Bean
CustomExchange testPluginDirectExchange() {
    HashMap<String, Object> args = new HashMap<>();
    args.put("x-delayed-type", "direct");
    return new CustomExchange(TestQueueEnum.QUEUE_TEST_PLUGIN.getExchange(), "x-delayed-message", true, false, args); // durable=true交换机持久化
}

/**
 * 声明队列
 **/
@Bean
public Queue testPluginQueue() { // durable=true队列持久化
    return new Queue(TestQueueEnum.QUEUE_TEST_PLUGIN.getQueue(),true,false,false);
}

/**
 * 将队列绑定交换机,并指定 bindingKey
 **/
@Bean
public Binding testPluginBinding(Queue testPluginQueue, CustomExchange testPluginDirectExchange) {
    return BindingBuilder.bind(testPluginQueue)
            .to(testPluginDirectExchange)
            .with(TestQueueEnum.QUEUE_TEST_PLUGIN.getRoutingKey())
            .noargs();
}
}

四、创建枚举配置类

**
 * 消息队列枚举配置类
 *
 * @since: 2021/10/6 16:27
 **/
@Getter
public enum TestQueueEnum {

    /**
     * 采用延时队列插件的方式实现,可以自定义交换机,让交换机拥有延迟发送消息能力,从而实现延迟队列效果
     *
     * 另外也可以采用死信队列的方式(死信队列交换机+处理队列交换机)、两个队列(死信队列+处理队列),延迟插件主需要创建一个交换机和一个队列,实现更简单明了
     * 这里定义交换机、队列和路由的名字,自己爱咋定义咋定义
     **/
    QUEUE_TEST_PLUGIN("test.direct", "test.test", "test.test");

    /**
     * 交换机名称
     **/
    private String exchange;

    /**
     * 队列名称
     **/
    private String queue;

    /**
     * 路由键
     **/
    private String routingKey;

    TestQueueEnum(String exchange, String queue, String routingKey) {
        this.exchange = exchange;
        this.queue = queue;
        this.routingKey = routingKey;
    }
}

五、创建生产者

/**
 * 生产者
 * @Date: 2021/10/6 16:17
 */
@Slf4j
@Component
public class TestProducer {
    @Autowired
    AmqpTemplate amqpTemplate;
    @Autowired
    RabbitTemplate rabbitTemplate;

@PostConstruct
private void init() {
    rabbitTemplate.setMandatory(true);
}

    public void sendTestMessage(TestBO testBO) {
        // 这里设置消息正确生产并到达交换机中,回调确认时的唯一标识,用来进行消息发送确认
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(cloudContractURLReplaceBO.getFileId());
        //给延时插件队列发送消息
        rabbitTemplate.convertAndSend(TestQueueEnum.QUEUE_TEST_PLUGIN.getExchange(), TestQueueEnum.QUEUE_TEST_PLUGIN.getRoutingKey(), testBO,  new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //给消息设置延迟毫秒值,通过给消息设置x-delay头来设置消息从交换机发送到队列的延迟时间
                message.getMessageProperties().setHeader("x-delay", testBO.getDelayTimes());
                message.getMessageProperties().setCorrelationId(testBO.getId());
                return message;
            }
        }, correlationData);
    }
}

六、创建消费者

/**
 * 消费者
 * @Author: 从改变自己开始
 * @Date: 2021/10/6 16:32
 */
@Slf4j
@Component
@RabbitListener(queues = "test.test", containerFactory = "rabbitListenerContainerFactory")
public class TestConsumer {
    @RabbitHandler
    public void handle(TestBO testBO, Channel channel, @Headers Map<String,Object> map) throws Exception{

        if (map.get("error")!= null){
            System.out.println("错误的消息");
            try {
                channel.basicNack((Long)map.get(AmqpHeaders.DELIVERY_TAG),false,true);      //否认消息
                return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            //这里写你的业务逻辑巴拉巴拉巴拉巴拉巴拉巴巴
            // TODO
            // 消息消费后确认
            channel.basicAck((Long)map.get(AmqpHeaders.DELIVERY_TAG),false);

        } catch (IOException e) {
            try {
                channel.basicNack((Long) map.get(AmqpHeaders.DELIVERY_TAG), false, true);      //否认消息
                log.info("否认消息");
                return;
            } catch (IOException ee) {
                log.error("否认消息异常");
                e.printStackTrace();
            }
           
            throw new Exception("错误信息:" + e);
        }

    }
}

七、消息回调(确认是否发送成功)

/**
 * 通过实现 ConfirmCallback 接口,
 * 消息发送到 Broker 后触发回调,
 * 确认消息是否到达 Broker 服务器,
 * 也就是只确认是否正确到达 Exchange 中
 * @Date: 2021/8/26 10:12
 */
@Component
@Slf4j
public class ConfirmCallback implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback{
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);            //指定 ConfirmCallback
        rabbitTemplate.setReturnCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) { // 发送成功!
            log.info("消息唯一标识:"+correlationData.getId());
//            log.info("发送确认结果:"+ack);
        } else {
//            log.error("消息唯一标识:"+correlationData.getId());
//            log.error("发送确认结果:"+ack);
//            log.error("失败原因:"+cause);
            //这里写发布失败后的处理逻辑,这里暂时不处理。
        }

    }

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.info("消息无法被路由,被服务器退回。msg:{}, replyCode:{}. replyText:{}, exchange:{}, routingKey :{}",
                new String(message.getBody()), replyCode, replyText, exchange, routingKey);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值