springboot2.x +rabbitmq使用和源码分析四(消费者-Listener使用)

序言:

当数据通过生产者产生到发送到exchange交换器,再通过设定的路由规则,经过routingKey,最终会落地到queue 中。这个时候引出了Listener消费者了。在第一章中有对RabbitAnnotationDrivenConfiguration该类中源码做过基本分析,该类最大的作用就是通过配置文件的设定用于构建RabbitListenerContainerFactory(该接口的实现,工厂设计模式用以创建核心的MessageListenerContainer

容器类,而该类MessageListenerContainer用以管理MessageListener,最终实现的该接口类操作Connection最终来消费数据)

对于spring提供了两种工厂实现,SimpleRabbitListenerContainerFactory与DirectRabbitListenerContainerFactoryConfigurer,

1:SimpleRabbitListenerContainerFactory(SMLC)

用于构建SimpleMessageListenerContainer在章节一中也描述了该模式下,rabbitmq的消费模式,该监听容器通过客户端多线程来并行的处理消息,通过上述的配置设置并行度。也可以监控多个队列并在运行时对队列进行增删。系统通过 concurrentConsumers、maxConcurrentConsumers 灵活设定当前容器中消费者的数量,不论监控多少个队列,channel与当前线程都会一一对应(这也是为何命令为Simple的因素),即使用同一consumer线程来会处理所有的队列。即这里我们先使用该模式来进行消费。

1.1:通过Factory构建SimpleMessageListenerContainer

当设置完成,我们如果在应用中创建SimpleMessageListenerContainer,来监听queue呢。spring也提供了两种方式

yml配置:

listener:
      type: simple
      simple:
        ##这里使用none后续对此进行详细描述
        acknowledge-mode: none
        auto-startup: true
        ##设置消费并行度
        concurrency: 2
        ##设置最大并行度
        max-concurrency: 2
        ##设置一个批次最大拉取数量
        batch-size: 3
        ##不开启重试 避免重复消费
        retry:
          enabled: false
        ## 每个消费者可能未完成的未确认消息的最大数量
        #prefetch:
        ## 若容器中声明的的queue不存在了(queue在代理上不可用或在运行时被删除了) 是否需要停止对应容器默认true
        missing-queues-fatal: true
        ## 默认情况下,拒绝交付是否重新排队
        default-requeue-rejected: true
        # 应该多久发布一次空闲容器事件 可用于监控
        idle-event-interval: 10000

1.1.1: MessageListener

单条消费,可以通过配置开启自动ack或不开启ack


    @Autowired
    private SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory;


    //单条消费
    @Bean
    public MessageListenerContainer simpleMessageListenerContainer(){

        SimpleMessageListenerContainer listenerContainer = simpleRabbitListenerContainerFactory.createListenerContainer();

        //设置被监控的queue
        listenerContainer.setQueueNames(CommonConstant.queue_direct1,CommonConstant.queue_direct2);

        //等待消息到达超时时间默认1s
        listenerContainer.setReceiveTimeout(1000);
        //手动确认
        listenerContainer.setAcknowledgeMode(AcknowledgeMode.NONE);
        //默认10s
        listenerContainer.setStartConsumerMinInterval(10*1000);
        //默认60s
        listenerContainer.setStopConsumerMinInterval(60*1000);
        //设置消费者唯一标记 基于queue设置
        listenerContainer.setConsumerTagStrategy(queue -> {
            return queue+"_"+ UUID.randomUUID().toString();
        });

        listenerContainer.setMessageListener(message->{
            //获取数据
            byte[] body = message.getBody();
            String str = new String(body);

            Thread thread=Thread.currentThread();
            log.info("message:{}  ThreadId is:{}  ConsumerTag:{}  Queue:{}"
                    ,str,thread.getId(),message.getMessageProperties().getConsumerTag(),message.getMessageProperties().getConsumerQueue());

        });

        return listenerContainer;

    }

 上述设置了2个并行情况,有两个线程(consumer)并行消费

 

1.1.2: ChannelAwareMessageListener

包含channel与message可以进行手动ack确定

    @Autowired
    private SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory;

    @Bean
    public MessageListenerContainer simpleChannelMessageListenerContainer(){

        SimpleMessageListenerContainer listenerContainer = simpleRabbitListenerContainerFactory.createListenerContainer();

        //设置被监控的queue
        listenerContainer.setQueueNames(CommonConstant.queue_direct1,CommonConstant.queue_direct2);

        //等待消息到达超时时间默认1s
        listenerContainer.setReceiveTimeout(1000);
        //手动确认
        listenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        //默认10s
        listenerContainer.setStartConsumerMinInterval(10*1000);
        //默认60s
        listenerContainer.setStopConsumerMinInterval(60*1000);
        //设置消费者唯一标记 基于queue设置
        listenerContainer.setConsumerTagStrategy(queue -> {
            return queue+"_"+ UUID.randomUUID().toString
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值