动态改变消费者 - rabbitMQ

时间:2018-04-25 05:11:29

标签: spring-rabbitmq

我正在努力动态改变消费者。但是,消费者的消费者一度超越了最大消费者。 代码是:

public class RabbitMQConfig extends AMQPConfig implements RabbitListenerConfigurer{

    @Autowired
    RabbitListenerEndpointRegistry endpoint; 
    static int temp=0;   
    SimpleMessageListenerContainer container;

    @Autowired
    private ConnectionFactory connectionFactory;

    @Autowired
    SimpleRabbitListenerContainerFactory  factory;

    @Override
    public void configureRabbitListeners(final RabbitListenerEndpointRegistrar registrar){
    registrar.setContainerFactory(rabbitListenerContainerFactory());
    registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
}

public AmqpTemplate getAmqpTemplate() {
    final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setMessageConverter ((MessageConverter)consumerJackson2MessageConverter());
    return rabbitTemplate;
}

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() 
{

    factory=new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(this.connectionFactory);
    factory.setConcurrentConsumers(15);
    factory.setMaxConcurrentConsumers(20);
    factory.setPrefetchCount(10);
    return factory;
}

public void  throttleConsumers(){

    Collection<MessageListenerContainer> containers= endpoint.getListenerContainers();
    SimpleMessageListenerContainer  eachSimpleMessageListenerContainer=null;
    for(MessageListenerContainer eachContainer : containers)
    {
    if(eachContainer.getClass().getName().equalsIgnoreCase("org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer")){
    eachSimpleMessageListenerContainer =(SimpleMessageListenerContainer)eachContainer;
    eachSimpleMessageListenerContainer.setConcurrentConsumers(12);
    }               
    }       
    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(this.connectionFactory);
    }

}

消费者是:

@Component
public class Consumer {

@Autowired
private AmqpTemplate rabbitTemplate;

@Value("${rabbitmq.queue}")
String queueName;   

static long messageCount=0L;

@Autowired
RabbitMQConfig config;

    @RabbitListener(queues="rabbitmq.queue")
    public void receivedMessage(String message) throws IOException {

    messageCount++;
    System.out.println(message);

    if(messageCount>10000 && messageCount<15000 )
    {
            System.out.println("consumed: "+messageCount);
            try
            {
                Thread.sleep(1000);
            }
            catch(Exception e)
            {
                System.out.println("error sleeping:"+e.getMessage());
            }

    config.throttleConsumers();
    rabbitTemplate.convertAndSend(queueName,message);
    RestTemplate restTemplate = new RestTemplate();
String quote = restTemplate.getForObject("http://localhost:8080/rabbitmq-consumer/throttle", String.class);
      System.out.println(quote);

    }


}

}

目前我的最小消费者是15岁,最多是20岁,一旦另一个节目的响应时间大于800,我就会限制为12岁。而我们正在测试消费者的数量达到29,这是我们无法理解的。

请帮助我们了解我们哪里出错了。

1 个答案:

答案 0 :(得分:0)

我只是用相似的代码测试它,如果我在达到最大值之前更改了min,就没有问题...

@SpringBootApplication
public class So50014436Application {

    public static void main(String[] args) {
        SpringApplication.run(So50014436Application.class, args).close();
    }

    @Bean
    public ApplicationRunner runner(RabbitTemplate template, AmqpAdmin admin,
            RabbitListenerEndpointRegistry registry) {
        return args -> {
            for (int i = 0; i < 1000; i++) {
                template.convertAndSend("so50014436", "foo");
            }
            ExecutorService exec = Executors.newSingleThreadExecutor();
            exec.execute(() -> {
                while (true) {
                    System.out.println(admin.getQueueProperties("so50014436"));
                    try {
                        Thread.sleep(5_000);
                    }
                    catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            });
            Thread.sleep(30_000);
            System.out.println("Changing min to 12");
            registry.getListenerContainers().forEach(c -> {
                ((SimpleMessageListenerContainer) c).setConcurrentConsumers(12);
            });
            Thread.sleep(60_000);
            exec.shutdownNow();
        };
    }

    @RabbitListener(queues = "so50014436")
    public void listen(String in) throws Exception {
        Thread.sleep(1_000);
    }

    @Bean
    public Queue queue() {
        return new Queue("so50014436");
    }

}

spring.rabbitmq.listener.simple.concurrency=10
spring.rabbitmq.listener.simple.max-concurrency=15

{QUEUE_CONSUMER_COUNT=10, QUEUE_MESSAGE_COUNT=832, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=10, QUEUE_MESSAGE_COUNT=978, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=10, QUEUE_MESSAGE_COUNT=933, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=11, QUEUE_MESSAGE_COUNT=883, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=11, QUEUE_MESSAGE_COUNT=830, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=12, QUEUE_MESSAGE_COUNT=774, QUEUE_NAME=so50014436}
Changing min to 12
{QUEUE_CONSUMER_COUNT=14, QUEUE_MESSAGE_COUNT=712, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=14, QUEUE_MESSAGE_COUNT=642, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=570, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=495, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=420, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=345, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=270, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=195, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=120, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=45, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}

但是,如果我等到达到最大值,我确实看到了问题......

{QUEUE_CONSUMER_COUNT=10, QUEUE_MESSAGE_COUNT=695, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=10, QUEUE_MESSAGE_COUNT=940, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=10, QUEUE_MESSAGE_COUNT=890, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=11, QUEUE_MESSAGE_COUNT=847, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=11, QUEUE_MESSAGE_COUNT=792, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=12, QUEUE_MESSAGE_COUNT=736, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=12, QUEUE_MESSAGE_COUNT=676, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=12, QUEUE_MESSAGE_COUNT=616, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=13, QUEUE_MESSAGE_COUNT=552, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=13, QUEUE_MESSAGE_COUNT=487, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=14, QUEUE_MESSAGE_COUNT=420, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=14, QUEUE_MESSAGE_COUNT=350, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=14, QUEUE_MESSAGE_COUNT=280, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=15, QUEUE_MESSAGE_COUNT=205, QUEUE_NAME=so50014436}
Changing min to 12
{QUEUE_CONSUMER_COUNT=17, QUEUE_MESSAGE_COUNT=128, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=17, QUEUE_MESSAGE_COUNT=43, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=17, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=17, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}
{QUEUE_CONSUMER_COUNT=16, QUEUE_MESSAGE_COUNT=0, QUEUE_NAME=so50014436}

...我们超越最大值。但不清楚为什么你有29岁。

我为此开了一个JIRA Issue

那就是说,当你已经达到最大值(15)时,你不清楚为什么要把min改为12。