RabbitMq基础篇-05-整合Springboot使用RabbitMQ

1. 整合Springboot使用RabbitMQ

1.导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.配置Yml

server:
  port: 9992
spring:
  application:
    name: rabbitmq-boot
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: wang
    password: wang
    virtual-host: /wang1

1.1 Hello模型

1.1.1 生产者

@SpringBootTest(classes = RabbitMqApplication.class)
@RunWith(SpringRunner.class)
public class provider {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 简单hello模型
     */
    @Test
    public void prodMessages(){
        rabbitTemplate.convertAndSend("hello","hello,我是简单hello模型");
    }

}

1.1.2 消费者

@Component   //不设置默认为 持久化,非独占,非自动删除队列
@RabbitListener(queuesToDeclare = @Queue(value = "hello", durable = "true", autoDelete = "false"))
public class consumer {

    @RabbitHandler
    public void consumerMessage(String message) {
        System.out.println("我是简单模型消费者消费消息为:" + message);
    }
}

注意:  当只有生产者没消费者时,队列是不会创建的,只有当消费者存在时才会自动创建

1.2 Work模型

1.2.1 生产者

@SpringBootTest(classes = RabbitMqApplication.class)
@RunWith(SpringRunner.class)
public class provider {

    @Autowired
    private RabbitTemplate rabbitTemplate;

 /**
 * 工作模型 work 和交换机没关系
 */
@Test
public void testWork() {

    for (int i = 0; i < 100; i++) {
        rabbitTemplate.convertAndSend("work", i + "hello,我是工作模型");
    }
}

}

1.2.2 消费者

默认情况下是公平消费,下面配的是能者多劳,目的为避免消息丢失
注意修改yml的配置

spring:
  application:
    name: rabbitmq-boot
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: wang
    password: wang
    virtual-host: /wang1
    #配置这个解决work模式中能者多劳的问题
    listener:
      simple:
        prefetch: 1   #每个消费者每次可以消费一个
/**
 * @version V1.0.0
 * @author: WangQingLong
 * @date: 2020/9/29 0:04
 * @description: 当@RabbitListener加在方法上,表面这个方法就是执行方法回调,就不需要加@RabbitHandler注解了,在springboot里面默认是循环公平消费,如果要配置能者多劳需要额外配置
 */
@Component
public class ConsumerWork {

    //ackMode:MANUAL 手动确认
    @RabbitListener(queuesToDeclare = @Queue(value = "work"), ackMode = "MANUAL")
    public void consumerMessage1(String msg, Message message, Channel channel) throws IOException {
        // 该条消息的消息编号,Long类型,递增的
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            //模拟网络延迟
            TimeUnit.SECONDS.sleep(1);

            // 模拟处理消息
            System.out.println("我是消费者1号:"+msg);

            // 处理成功 手动ACK回执
            // arg0:消息编号 递增的 该消息的index
            // arg1: 是否批量.true:将一次性ack所小于deliveryTag的消息。
            //        true: 将一次性ACK回执成功所小于消息编号(deliveryTag的消息
            //		 false:仅ACK回执成功传入的消息编号(deliveryTag
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {

            // 当消息处理异常时,将消息重新放回队列,重新排队
            // arg0:消息编号 递增的 该消息的index
            // arg1: 是否批量.true:将一次性拒绝所有小于deliveryTag的消息。
            //       true: 将一次性拒绝所有小于消息编号(deliveryTag的消息
            //		false:仅拒绝传入的消息编号(deliveryTag
            // arg2:true: 让消息重新回到队列
            // 		false:直接丢弃消息

            //注意 对比
            // channel.basicReject(delivery.getEnvelope().getDeliveryTag(), false);
            //deliveryTag:该消息的index
            //requeue:被拒绝的是否重新入队列
            //
            //channel.basicNack 与 channel.basicReject 的区别在于basicNack可以拒绝多条消息,而basicReject一次只能拒绝一条消息


            channel.basicNack(deliveryTag, false, true);
        }
    }

    //ackMode:MANUAL 手动确认
    @RabbitListener(queuesToDeclare = @Queue(value = "work"), ackMode = "MANUAL")
    public void consumerMessage2(String msg, Message message, Channel channel) throws IOException {
        // 该条消息的消息编号,Long类型,递增的
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            // 模拟处理消息
            System.out.println("我是消费者2号:"+msg);

            // 处理成功 手动ACK回执
            // arg0:消息编号 递增的 该消息的index
            // arg1: 是否批量.true:将一次性ack所小于deliveryTag的消息。
            //        true: 将一次性ACK回执成功所小于消息编号(deliveryTag的消息
            //		 false:仅ACK回执成功传入的消息编号(deliveryTag
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {

            // 当消息处理异常时,将消息重新放回队列,重新排队
            // arg0:消息编号 递增的 该消息的index
            // arg1: 是否批量.true:将一次性拒绝所有小于deliveryTag的消息。
            //       true: 将一次性拒绝所有小于消息编号(deliveryTag的消息
            //		false:仅拒绝传入的消息编号(deliveryTag
            // arg2:true: 让消息重新回到队列
            // 		false:直接丢弃消息

            //注意 对比
            // channel.basicReject(delivery.getEnvelope().getDeliveryTag(), false);
            //deliveryTag:该消息的index
            //requeue:被拒绝的是否重新入队列
            //
            //channel.basicNack 与 channel.basicReject 的区别在于basicNack可以拒绝多条消息,而basicReject一次只能拒绝一条消息


            channel.basicNack(deliveryTag, false, true);
        }
    }
}

1.3 Fanout广播模型

1.3.1 生产者

@SpringBootTest(classes = RabbitMqApplication.class)
@RunWith(SpringRunner.class)
public class provider {

    @Autowired
    private RabbitTemplate rabbitTemplate;

/**
 * 广播模型 fanout 交换机但是和路由没关系
 */
@Test
public void testFanout() {
    rabbitTemplate.convertAndSend("FanoutExchange", "", "我是广播模型生产者");
}

}

1.3.2 消费者

@Component
public class ConsumerFanout {


    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//如果不指定名字就是临时队列
                    exchange = @Exchange(value = "FanoutExchange", type = "fanout")
            )
    })
    public void consumerMessage1(String message) {
        System.out.println("我是广播模型消费者1号:" + message);
    }


    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//如果不指定名字就是临时队列
                    exchange = @Exchange(value = "FanoutExchange", type = "fanout")
            )
    })
    public void consumerMessage2(String message) {
        System.out.println("我是广播模型消费者2号:" + message);
    }


    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//如果不指定名字就是临时队列
                    exchange = @Exchange(value = "FanoutExchange", type = "fanout")
            )
    })
    public void consumerMessage3(String message) {
        System.out.println("我是广播模型消费者3号:" + message);
    }
}

1.4 Route路由模型

1.4.1 生产者

@SpringBootTest(classes = RabbitMqApplication.class)
@RunWith(SpringRunner.class)
public class provider {

    @Autowired
    private RabbitTemplate rabbitTemplate;


/**
 * 路由模型 Route  交换机固定路由
 */
@Test
public void testRoute() {
    rabbitTemplate.convertAndSend("RouteExchange", "info", "我是广播模型生产者");
}


}

1.4.2 消费者

@Component
public class ConsumerRoute {

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange = @Exchange(value = "RouteExchange",type = "direct"),
                    key = {"info","error"}
            )
    })
    public void consumerMessage1(String message){
        System.out.println("我是路由模型消费者1号,指向路由info和error = " + message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange = @Exchange(value = "RouteExchange",type = "direct"),
                    key = {"error"}
            )
    })
    public void consumerMessage2(String message){
        System.out.println("我是路由模型消费者1号,指向路由error = " + message);
    }
}

1.5 Topic订阅模型/动态路由模型

1.5.1 生产者

@SpringBootTest(classes = RabbitMqApplication.class)
@RunWith(SpringRunner.class)
public class provider {

    @Autowired
    private RabbitTemplate rabbitTemplate;

/**
 * 订阅模型 Topics  也叫动态路由  交换机动态路由
 */
@Test
public void testTopics() {
    rabbitTemplate.convertAndSend("TopicsExchange", "user.save", "我是订阅模型生产者");
}

}

1.5.2 消费者

@Component
public class ConsumerTopics {

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange = @Exchange(value = "TopicsExchange",type = "topic"),
                    key = {"user.*"}
            )
    })
    public void consumerMessage1(String message){
        System.out.println("我是路由模型消费者1号,指向路由user.* = " + message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange = @Exchange(value = "TopicsExchange",type = "topic"),
                    key = {"user.*","order.#"}
            )
    })
    public void consumerMessage2(String message){
        System.out.println("我是路由模型消费者2号,指向路由user.*\",\"order.# = " + message);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alan0517

感谢您的鼓励与支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值