Kafka源码之KafkaConsumer分析之poll方法分析

我们获取消息都是通过poll方法,现在我们从整体上看一下消费的流程:

public ConsumerRecords poll(long timeout) {
		//防止并发操作
        acquire();
        try {
            if (timeout < 0)
                throw new IllegalArgumentException("Timeout must not be negative");

            //获取拉取消息的开始时间
            long start = time.milliseconds();
            long remaining = timeout;
            do {
            	//在规定时间内拉取一次消息
                Map>> records = pollOnce(remaining);
                if (!records.isEmpty()) {
                    //如果拉取到了消息,发送一次消息拉取的请求,不会阻塞不会被中断
                    fetcher.sendFetches();
                    client.pollNoWakeup();
					//经过拦截器处理后返回
                    if (this.interceptors == null)
                        return new ConsumerRecords<>(records);
                    else
                        return this.interceptors.onConsume(new ConsumerRecords<>(records));
                }
				//如果没有获取到消息再次尝试获取
                long elapsed = time.milliseconds() - start;
                remaining = timeout - elapsed;
            } while (remaining > 0);

            return ConsumerRecords.empty();
        } finally {
        	//释放
            release();
        }
    }

我们看这个方法首先调用了acquire防止并发操作,然后先尝试在规定时间内拉取一次消息,如果拉取到了消息,那么在执行一次非阻塞不能中断的请求,返回经过拦截器处理的消息集合:

private Map>> pollOnce(long timeout) {
        // 确保和coordinator连接好了
        coordinator.ensureCoordinatorReady();

        // 完成rebalace操作
        if (subscriptions.partitionsAutoAssigned())
            coordinator.ensurePartitionAssignment();

        // 更新position
        if (!subscriptions.hasAllFetchPositions())
            updateFetchPositions(this.subscriptions.missingFetchPositions());

        long now = time.milliseconds();

        // 执行定时任务
        client.executeDelayedTasks(now);

        //尝试从completed结合中获取消息
        Map>> records = fetcher.fetchedRecords();

        //获取到了直接返回
        if (!records.isEmpty())
            return records;
	//没有需要请求从服务端获取
        fetcher.sendFetches();
        client.poll(timeout, now);
        return fetcher.fetchedRecords();
    }

你可能感兴趣的:(Kafka)