关系图
类说明
InternalConsumer:
BlockingQueueConsumer的内部类,实现了<amqp-client>的DefaultConsumer类,实际的RabbitMQ Client消费者;一个InternalConsumer对应一个queue,非阻塞地从RabbitMQ Server中接收消息。
private final class InternalConsumer extends DefaultConsumer {
private final String queueName;
private boolean canceled;
InternalConsumer(Channel channel, String queue) {
super(channel);
this.queueName = queue;
}
// 省略...
}
BlockingQueueConsumer:
内部类InternalConsumer接收消息,并存放在BolckingQueue<Delivery>中(LinkedBolckingQueue是Java内部提供的阻塞对列),对外提供阻塞方法nextMessage消费消息,形成生产者消费者模式;
prefetchCount参数为LinkedBolckingQueue对列长度,同时也是basicQos,即一个consumer从RabbitMQ Server预取的消息数量,默认为250个。
public BlockingQueueConsumer(ConnectionFactory connectionFactory,
MessagePropertiesConverter messagePropertiesConverter,
ActiveObjectCounter<BlockingQueueConsumer> activeObjectCounter, AcknowledgeMode acknowledgeMode,
boolean transactional, int prefetchCount, boolean defaultRequeueRejected,
@Nullable Map<String, Object> consumerArgs, boolean noLocal, boolean exclusive, String... queues) {
this.connectionFactory = connectionFactory;
this.messagePropertiesConverter = messagePropertiesConverter;
this.activeObjectCounter = activeObjectCounter;
this.acknowledgeMode = acknowledgeMode;
this.transactional = transactional;
this.prefetchCount = prefetchCount;
this.defaultRequeueRejected = defaultRequeueRejected;
if (consumerArgs != null && consumerArgs.size() > 0) {
this.consumerArgs.putAll(consumerArgs);
}
this.noLocal = noLocal;
this.exclusive = exclusive;
this.queues = Arrays.copyOf(queues, queues.length);
this.queue = new LinkedBlockingQueue<Delivery>(queues.length == 0 ? prefetchCount : prefetchCount * queues.length);
}
AsyncMessageProcessingConsumer:
SimpleMessageListenerContainer的内部类,管理BlockingQueueConsumer,实现了Runnable接口,最终由SimpleAsyncTaskExecutor线程池运行;
AsyncMessageProcessingConsumer(BlockingQueueConsumer consumer) {
this.consumer = consumer;
this.start = new CountDownLatch(1);
}
负载动态调整逻辑
1、默认线程数concurrentConsumers = 1,运行时始终保持开启的消费者数量,即对应的BlockingQueueConsumer数量;
protected int initializeConsumers() {
int count = 0;
synchronized (this.consumersMonitor) {
if (this.consumers == null) {
this.cancellationLock.reset();
this.consumers = new HashSet<BlockingQueueConsumer>(this.concurrentConsumers);
for (int i = 1; i <= this.concurrentConsumers; i++) {
BlockingQueueConsumer consumer = createBlockingQueueConsumer();
if (getConsumeDelay() > 0) {
consumer.setConsumeDelay(getConsumeDelay() * i);
}
this.consumers.add(consumer);
count++;
}
}
}
return count;
}
2、默认最大线程数maxConcurrentConsumers为空,此时仅维持固定的消费者数量,设置了之后动态增加和减少消费者。
3、默认任意一个线程连续10次接收到消息,且距离上次添加线程超过10秒,则增加新的消费者,可通过设置startConsumerMinInterval、consecutiveActiveTrigger调整;
private void considerAddingAConsumer() {
synchronized (this.consumersMonitor) {
if (this.consumers != null
&& this.maxConcurrentConsumers != null && this.consumers.size() < this.maxConcurrentConsumers) {
long now = System.currentTimeMillis();
if (this.lastConsumerStarted + this.startConsumerMinInterval < now) {
this.addAndStartConsumers(1);
this.lastConsumerStarted = now;
}
}
}
}
4、默认任意一个线程连续10次接收不到消息,且距离上次关闭线程超过60秒,则移除当前消费者,可通过设置stopConsumerMinInterval、consecutiveIdleTrigger调整;
private void considerStoppingAConsumer(BlockingQueueConsumer consumer) {
synchronized (this.consumersMonitor) {
if (this.consumers != null && this.consumers.size() > this.concurrentConsumers) {
long now = System.currentTimeMillis();
if (this.lastConsumerStopped + this.stopConsumerMinInterval < now) {
consumer.basicCancel(true);
this.consumers.remove(consumer);
if (logger.isDebugEnabled()) {
logger.debug("Idle consumer terminating: " + consumer);
}
this.lastConsumerStopped = now;
}
}
}
}