Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

ความแตกต่างระหว่าง Apache Kafka และ JMS (Java Message Service)

ทั้งคู่เป็น **Messaging Systems** แต่มี architecture และ use cases ต่างกันมาก

ตารางเปรียบเทียบ

ลำดับหัวข้อApache KafkaJMS (Java Message Service)
1พื้นฐานDistributed commit log / Event streaming platformAPI สำหรับ Message Oriented Middleware (MOM)
2ModelPublish-Subscribe + Consumer Groups (Hybrid)Point-to-Point (Queue) + Pub/Sub (Topic)
3Mechanism**Pull** - Consumer poll ข้อมูลเอง**Push** - Broker push ให้ Consumer
4Message RetentionPolicy-based (เวลา/ขนาด) - เก็บได้นาน/ถาวรAcknowledgment-based - ลบหลัง consume แล้ว
5Ordering** đảm bảo** ต่อ partitionไม่รับประกัน ordering (ขึ้นกับ provider)
6RebalancingAuto rebalance เมื่อ consumer join/leave groupไม่มี built-in (ขึ้นกับ provider)
7ScalabilityHorizontal scaling ด้วย partitionsจำกัดโดย queue/topic architecture
8Replayability✅ อ่านซ้ำได้ (offset management)❌ ทั่วไปไม่รองรับ (ข้อความหายหลัง ack)
9Throughputสูงมาก (millions msg/sec)ปานกลาง (ขึ้นกับ implementation)
10ProtocolCustom binary protocol over TCPJMS API (provider-specific wire protocol)

Kafka: Pull-based Consumer Groups

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  Producer   │────▶│   Topic      │◀───▶│  Consumer   │
│  (Writer)   │     │  (Partitions)│     │  Group      │
└─────────────┘     └──────────────┘     └─────────────┘
                           │
                    ┌──────┴──────┐
                    ▼           ▼
              Partition 0   Partition 1
              (offset 0..n) (offset 0..n)
  • Producers เขียนต่อ partition (round-robin หรือ key-based)
  • Consumers ใน group เดียว แบ่งกันอ่าน partitions (1 partition = 1 consumer)
  • Offset เก็บว่าแต่ละ consumer อ่านถึงไหน → **Replay ได้**

JMS: Push-based Queues/Topics

Point-to-Point (Queue):          Publish/Subscribe (Topic):
┌─────────┐    ┌───────┐         ┌─────────┐    ┌───────┐
│Producer │───▶│ Queue │         │Producer │───▶│ Topic │
└─────────┘    └───┬───┘         └─────────┘    └───┬───┘
                   │                                  │
            ┌──────┴──────┐                   ┌──────┴──────┐
            ▼             ▼                   ▼             ▼
        Consumer 1   Consumer 2           Subscriber 1  Subscriber 2
        (competing)  (only 1 gets msg)    (both get msg) (both get msg)
  • Queue: 1 message → 1 consumer (competing consumers)
  • Topic: 1 message → all subscribers (broadcast)
  • Message ถูกลบหลัง ack → **Replay ไม่ได้**

เมื่อไหร่ควรใช้ Kafka?

  • 🔄 **Event Sourcing / CQRS** - ต้องการ replay events
  • 📊 **Log Aggregation / Metrics** - High throughput, retention
  • 🔗 **Microservices Communication** - Async, decoupled, replayable
  • 📈 **Stream Processing** - Kafka Streams, ksqlDB, Flink
  • 🌐 **Multi-consumer patterns** - Group + broadcast พร้อมกัน

เมื่อไหร่ควรใช้ JMS?

  • 📋 **Traditional Enterprise Apps** - มี JMS provider อยู่แล้ว (ActiveMQ, IBM MQ, WebLogic)
  • ✅ **Guaranteed Delivery once** - ไม่ต้อง replay, แค่ส่งถึงปลายทาง
  • 🔧 **Simple Queue/Topic needs** - ไม่ต้องการ complexity ของ Kafka
  • 🏢 **Legacy Integration** - ระบบเก่าที่ใช้ JMS API อยู่แล้ว
  • 💰 **Transactional Messaging** - JTA/XA transactions (Kafka มี transactions แต่ซับซ้อนกว่า)

Code Comparison

Kafka Producer/Consumer (Java)

// Producer
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("my-topic", "key", "value"));

// Consumer
props.put("group.id", "my-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("my-topic"));
while (true) {
    ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
    for (ConsumerRecord record : records) {
        System.out.println(record.value());
    }
}

JMS (ActiveMQ Example)

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// Queue (Point-to-Point)
Queue queue = session.createQueue("MY_QUEUE");
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello Queue"));

// Topic (Pub/Sub)
Topic topic = session.createTopic("MY_TOPIC");
MessageProducer topicProducer = session.createProducer(topic);
topicProducer.send(session.createTextMessage("Hello Topic"));

connection.start();
// Consumer code similar...

สรุป

Kafka = Event Streaming Platform (High throughput, Replay, Distributed log)
JMS = Traditional Messaging API (Queue/Topic, Push, Acknowledgment-based)

เลือก Kafka สำหรับ Modern event-driven architectures | เลือก JMS สำหรับ Enterprise legacy integration