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

ความแตกต่างระหว่าง Point-to-Point และ Publish/Subscribe ใน JMS

JMS (Java Message Service) รองรับ 2 โมเดลการส่งข้อความหลัก:

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

ลำดับหัวข้อPoint-to-Point (PTP) - QueuePublish/Subscribe (Pub/Sub) - Topic
1พื้นฐานOne-to-One: ข้อความ 1 ตัว → 1 ConsumerOne-to-Many: ข้อความ 1 ตัว → หลาย Subscribers
2DestinationQueueTopic
3MechanismPull - Consumer poll/receive เองPush - Broker ส่งให้ Subscribers ทุกตัว
4Message Consumption**Competing Consumers**: หลาย consumer แต่อ่านคนละ msg (load balancing)**Broadcast**: ทุก subscriber ได้ message ทุกตัว
5Acknowledgmentบังคับ (Client/ Auto/ Dups_ok)Optional (ขึ้นกับ subscription type)
6Timing Dependencyไม่มี - Sender/Receiver ไม่ต้อง online พร้อมกันมี - Subscriber ต้อง online (durable subscriber ได้)
7Message Retentionจนกว่าจะถูก consume + ackจนกว่าจะส่งให้ทุก durable subscriber แล้ว
8Use CaseTask distribution, Work queues, Load balancingBroadcast, Notifications, Event distribution

Point-to-Point (Queue) - รายละเอียด

Producer → [Queue] → Consumer 1 (gets msg 1)
                  → Consumer 2 (gets msg 2)
                  → Consumer 3 (gets msg 3)
                  
• 1 message = 1 consumer only (competing)
• Message อยู่ใน queue จนกว่าจะถูก consume + ack
• Sender ไม่ต้องรู้ว่าใครจะ receive
• เหมาะสำหรับ: Job queue, Task distribution, Load balancing

โค้ดตัวอย่าง PTP

// Sender
Queue queue = session.createQueue("TASK_QUEUE");
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Process order #123"));

// Receiver (หลายตัวรันพร้อมกันได้ - competing)
MessageConsumer consumer = session.createConsumer(queue);
connection.start();
TextMessage msg = (TextMessage) consumer.receive(); // Block จนกว่าจะมี msg
System.out.println("Received: " + msg.getText());

Publish/Subscribe (Topic) - รายละเอียด

Publisher → [Topic] → Subscriber A (gets msg)
                    → Subscriber B (gets msg)
                    → Subscriber C (gets msg)
                    
• 1 message = ทุก subscribers ได้รับ (broadcast)
• Subscriber ต้อง subscribe ก่อน publish (เว้นแต่ Durable)
• เหมาะสำหรับ: Notifications, Events, Stock prices, Alerts

Subscription Types

ประเภทคำอธิบาย
Non-durableSubscriber ต้อง online ตอน publish → หายไปถ้า offline
DurableServer เก็บ message ไว้ให้ subscriber ที่ offline → ได้ message ตอนกลับมา
Shared (JMS 2.0+)หลาย consumers แบ่งกันรับจาก topic เดียว (competing на topic)

โค้ดตัวอย่าง Pub/Sub

// Publisher
Topic topic = session.createTopic("STOCK_PRICES");
MessageProducer publisher = session.createProducer(topic);
publisher.send(session.createTextMessage("AAPL: 150.25"));

// Durable Subscriber (ได้ message แม้ offline)
Topic topic = session.createTopic("STOCK_PRICES");
MessageConsumer subscriber = session.createDurableConsumer(topic, "subscriber-1");
connection.start();
Message msg = subscriber.receive(); // ได้ message แม้ส่งตอน offline

JMS 2.0+ Simplified API

// JMS 2.0 - ใช้ JMSContext (auto-closeable)
try (JMSContext context = factory.createContext()) {
    // Send to Queue
    context.createProducer().send(context.createQueue("QUEUE"), "Message");
    
    // Send to Topic
    context.createProducer().send(context.createTopic("TOPIC"), "Broadcast");
    
    // Receive (synchronous)
    String body = context.createConsumer(context.createQueue("QUEUE"))
                         .receiveBody(String.class);
    
    // Async listener
    context.createConsumer(context.createTopic("TOPIC"))
           .setMessageListener(msg -> System.out.println("Got: " + msg.getBody(String.class)));
}

สรุปการเลือกใช้

สถานการณ์เลือกเหตุผล
Work distribution (หลาย worker แบ่งงาน)Queue (PTP)Competing consumers, load balancing
Event notification (ทุก service ต้องรู้)Topic (Pub/Sub)Broadcast to all interested parties
Order processing (1 order → 1 processor)QueueExactly-once processing per order
Price updates / AlertsTopicMultiple subscribers need same data
Audit log / Audit trailTopic (Durable)Multiple consumers, replay capability

ข้อสังเกตเพิ่มเติม

  • JMS เป็น **API/Spec** ไม่ใช่ implementation → ต้องมี Provider (ActiveMQ, RabbitMQ, IBM MQ, WebLogic, ...)
  • Kafka 結合了 2 โมเดล: Consumer Group = PTP (competing) + Multiple Groups = Pub/Sub (broadcast)
  • Modern apps มักใช้ Kafka/RabbitMQ/gRPC แทน JMS โดยตรง