Что такое Pull-модель (модель подписки с опросом) в брокерах сообщений?

«Что такое Pull-модель (модель подписки с опросом) в брокерах сообщений?» — вопрос из категории Брокеры сообщений, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Pull-модель (модель подписки с опросом) — это подход к доставке сообщений, при котором потребитель (consumer) активно и периодически запрашивает ("тянет") новые сообщения из очереди или топика. Инициатива получения данных всегда исходит от клиента.

Принцип работы:

  1. Потребитель подключается к очереди/топику.
  2. В цикле он вызывает метод poll() (или аналогичный), указывая таймаут ожидания.
  3. Брокер возвращает пакет (batch) доступных сообщений или пустой результат, если сообщений нет.
  4. Потребитель обрабатывает сообщения и подтверждает их получение (commit offset).
  5. Цикл повторяется.

Пример на Apache Kafka Consumer API:

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "my-consumer-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("enable.auto.commit", "false"); // Ручное подтверждение
props.put("max.poll.records", 500); // Максимум сообщений за один poll

try (KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props)) {
    consumer.subscribe(List.of("my-topic"));
    while (true) {
        // Потребитель "тянет" сообщения. Таймаут 100 мс.
        ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
        for (ConsumerRecord<String, String> record : records) {
            System.out.printf("Partition=%d, Offset=%d, Key=%s, Value=%s%n",
                record.partition(), record.offset(), record.key(), record.value());
            // Обработка сообщения...
        }
        // Ручное подтверждение обработки всех сообщений в batch
        consumer.commitSync();
    }
}

Преимущества Pull-модели:

  • Контроль скорости потребления: Клиент сам решает, когда и сколько сообщений запросить, что предотвращает его перегрузку (backpressure control).
  • Эффективная batch-обработка: Можно запрашивать и обрабатывать сообщения пачками, повышая пропускную способность.
  • Справедливое распределение: В системах вроде Kafka позволяет легко балансировать нагрузку между потребителями в группе.
  • Повторная обработка: Клиент может управлять смещением (offset) для повторного чтения сообщений.

Недостатки Pull-модели:

  • Задержка (latency): Сообщения лежат в очереди до следующего опроса. Не подходит для систем, требующих мгновенной доставки.
  • Холостой опрос (busy-waiting): Если сообщений нет, вызовы poll() возвращают пустой результат, тратя ресурсы CPU и сети.
  • Сложность реализации: Клиенту необходимо управлять циклом опроса, таймаутами и подтверждениями.

Где используется? Apache Kafka, RabbitMQ (в режиме basic.get), Amazon SQS (стандартные очереди). Альтернатива — Push-модель, где брокер сам отправляет сообщения подключенным потребителям (например, RabbitMQ с AMQP, MQTT).