DEV Community

Cover image for 🐰 Kafka и Spring: Почтовый голубь против почтовой службы 🌸
Olga Lugacheva
Olga Lugacheva

Posted on

🐰 Kafka и Spring: Почтовый голубь против почтовой службы 🌸

Представьте весенний лес. Солнышко светит, цветочки распускаются, птички щебечут, а зайчики 🐰 дружно решили поздравить друг друга с весной!

Но тут встаёт вопрос: как быстро доставить открытки всем друзьям?

У зайчика Санни есть два варианта:

Почтовый голубь 🕊️ – берёт письмо и летит к получателю. Правда, иногда задерживается, может устать или вообще перепутать адрес.
Супер-зайцевая почтовая служба Kafka 🚀 – распределяет все открытки в мгновение ока, без ожиданий и задержек.
Вот так же в программировании различается синхронность (когда ждём, пока голубь долетит) и асинхронность (когда всё отправляется моментально через Kafka).

Давайте поможем зайчикам разослать поздравления! 🐇✨

🕊️ Почтовый голубь: как работает синхронность

bird
Сначала наш зайчик Санни попробовал отправлять поздравления через обычный REST-контроллер.

@RestController
@RequestMapping("/greetings")
public class GreetingController {

    @GetMapping("/{name}")
    public String sendGreeting(@PathVariable String name) {
        return "🌸 Привет, " + name + "! С первым днём весны! 🐰";
    }
}

Enter fullscreen mode Exit fullscreen mode

Каждый зайчик отправляет открытку и ждёт ответа. Пока письмо не доставлено – следующий не отправить.

📬 Kafka: быстрая зайцевая почта

kafka
Санни решил создать настоящую почтовую службу для зайчиков с Kafka! Теперь сообщения отправляются в специальный "почтовый центр", где их обрабатывают супер-зайцы-почтальоны.

🛠️ Настройка Kafka в Spring Boot
Добавляем зависимости в pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
</dependency>

Enter fullscreen mode Exit fullscreen mode

Настраиваем application.yml:

spring:
  kafka:
    bootstrap-servers: localhost:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
    consumer:
      group-id: bunny-post-group
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
Enter fullscreen mode Exit fullscreen mode

Теперь наш почтовый центр готов работать! 🏡📮

🐇📩 Отправляем поздравления зайцам
Санни создал производителя (producer), который отправляет открытки в лесную почту.

@Component
public class GreetingProducer {

    private final KafkaTemplate<String, String> kafkaTemplate;

    public GreetingProducer(KafkaTemplate<String, String> kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    public void sendGreeting(String name) {
        String message = "Привет, " + name + "! Весеннего тебе настроения! 🌸";
        kafkaTemplate.send("bunny-greetings", message);
    }
}

Enter fullscreen mode Exit fullscreen mode
@RestController
@RequestMapping("/greetings")
public class GreetingController {

    private final GreetingProducer producer;

    public GreetingController(GreetingProducer producer) {
        this.producer = producer;
    }

    @PostMapping("/{name}")
    public String sendGreeting(@PathVariable String name) {
        producer.sendGreeting(name);
        return "Твоя открытка   для  🌸"+ name + "🌸 отправлена 🐰";
    }
}
Enter fullscreen mode Exit fullscreen mode

logbef0

Зайчики теперь могут отправлять поздравления без ожиданий!

🐰📬 Почтальоны-консьюмеры: доставляем открытки

Теперь создадим консьюмера (consumer) – зайцев, которые разносят открытки по лесу.

@Component
public class GreetingConsumer {

    @KafkaListener(topics = "bunny-greetings", groupId = "bunny-post-group")
    public void receiveGreeting(String message) {
        System.out.println("📩 Зайчик получил сообщение: " + message);
    }
}

Enter fullscreen mode Exit fullscreen mode

Еще немного технических деталей:

Kafka должна быть запущена
Если у тебя её ещё нет, можно поднять Kafka локально через Docker:

docker-compose up -d

Enter fullscreen mode Exit fullscreen mode

Один из вариантов docker-compose.yml для Kafka и Zookeeper:

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper:latest
    container_name: zookeeper
    ports:
      - "2181:2181"

  kafka:
    image: wurstmeister/kafka:latest
    container_name: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    depends_on:
      - zookeeper
Enter fullscreen mode Exit fullscreen mode

Теперь каждый зайчик асинхронно получает своё поздравление, даже если отправителей много.

🌸Финальный результат

Теперь лесная почта работает так:

log0

🐇 Зайчик отправляет поздравление → Оно уходит в Kafka.
🚀 Kafka мгновенно раздаёт открытки всем зайцам-почтальонам.
📩 Каждый зайчик получает сообщение, не дожидаясь других.
Всё работает параллельно и без задержек. Теперь никакие зайцы не останутся без поздравлений!

Итог

Почтовый голубь Rest (синхронность) – всё работает, но медленно.
Kafka (асинхронность) – сообщения передаются мгновенно, без ожидания!
Spring Boot + Kafka позволяют легко отправлять и получать сообщения.
Зайчики довольны, весна пришла, а поздравления разосланы! 🌷🐰

Поздравляйте друзей правильно – асинхронно с Kafka! 🎉

Top comments (0)