Springboot 2.x integrates Rabbitmq to achieve consumer current limit, manual ack confirmation

Preface

In our actual project, we may have accumulated thousands of messages in mq. If we do not limit the flow, when we open the consumer, thousands of messages will suddenly hit over, which may cause the server Downtime, or serious loopholes in the business, so we need to limit consumer current.

First of all my springboot version, springBootVersion = '2.2.1.RELEASE'. The configurations of other versions are not much different.

First look at the configuration, here only the configuration without comments is used:

server:
  port: 3002

spring:
  application:
    name: zoo-plus-mq
    #https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/html/common-application-properties.html
  rabbitmq:
    virtual-host: /
    host: 127.0.0.1
    username: guest
    password: guest
    port: 5672
#    #必须配置这个才会确认回调
#    publisher-confirm-type: correlated
#    #支持发布返回
#    publisher-returns: true
    listener:
      type: simple
      simple:
        #采用手动应答
        acknowledge-mode: manual
        prefetch: 1 #限制每次发送一条数据。
#        #当前监听容器数 同一个队列启动几个消费者
#        concurrency: 1
#        #启动消费者最大数量
#        max-concurrency: 1
#        #是否支持重试
#        retry:
#          enabled: true
#          max-attempts: 5
#          stateless: false
#          #时间策略乘数因子
#          multiplier: 1.0
#          initial-interval: 1000ms
#          max-interval: 10000ms
#        default-requeue-rejected: true

Create a new test queue:

    /**
     * 测试队列
     */
    @Bean
    public Queue testQueue() {
        return QueueBuilder.nonDurable("test-queue").build();
    }

Producer:


    /**
     * 发送五条数据,测试消费端必须ack才发送第二条,消费者限流
     */
    @GetMapping("ack")
    public Resp testAck() {
        for (int i = 0; i < 5; i++) {
            rabbitTemplate.convertAndSend("test-queue", "测试ack确认模式");
        }
        return Resp.success("ok", null);
    }

consumer:

    @RabbitListener(queues = {"test-queue"})
    public void testQueue(Message message, Channel channel) throws IOException {
        log.info("test-queue消费:" + new String(message.getBody()));

        /*
              listener:
                type: simple
                simple:
                  #采用手动应答
                  acknowledge-mode: manual
                  prefetch: 1 #限制每次发送一条数据。
         */
//        采用手动ack,一条条的消费
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

From the above test, if we do not configure, all five messages will be crowded up at once. If we add configuration and do not ack on the consumer side, the message will be unacked, and the message will be sent again next time the service is restarted. Until the consumer end ack.

Guess you like

Origin blog.csdn.net/qq_36850813/article/details/103288667