JMS (Java Message Service) 是 Java EE 規範定義的消息中間件統一 API,屏蔽底層消息系統(如 ActiveMQ、RabbitMQ、Kafka、IBM MQ)差異,提供標準化的生產/消費、點對點/發布訂閱、事務/確認等機制,實現應用解耦、削峰填谷、異步處理、最終一致性等核心架構模式。


Durable Subscription 允許離線訂閱者重新上線時收到離線期間消息| 決策因子 | 選擇 Queue (P2P) | 選擇 Topic (Pub/Sub) |
|---|---|---|
| 消費者數量 | 單消費者或負載均衡多消費者 | 多消費者廣播 |
| 消息語義 | 命令/任務:必須被執行一次 | 事件/通知:感興趣者皆可知曉 |
| 時間耦合度 | 低(消息持久化) | 高(需持久訂閱降低) |
| 擴展性 | 水平擴展消費者實例 | 動態增減訂閱者 |
Message message = consumer.receive(); // 阻塞等待 Message message = consumer.receive(5000); // 超時 5 秒 Message message = consumer.receiveNoWait(); // 非阻塞輪詢
適用於簡單、低併發、需即時處理的場景。阻塞模式下線程被佔用,吞吐量受限。
consumer.setMessageListener(message -> {
try {
// 處理業務邏輯
processMessage(message);
message.acknowledge(); // 手動確認模式下需顯式 ACK
} catch (JMSException e) {
// 異常處理、重試、死信隊列
handleFailure(message, e);
}
});
容器管理線程池,高併發、非阻塞、吞吐量高。Spring @JmsListener、MDB (Message-Driven Bean) 均基於此模式。

管理連接池、認證、客戶端 ID 等。兩類:QueueConnectionFactory、TopicConnectionFactory,或統一 ConnectionFactory (JMS 1.1+)。通過 JNDI 查找或 Spring 注入。
Queue:點對點隊列,JNDI 名如 queue/orderQueueTopic:發布訂閱主題,JNDI 名如 topic/priceTopic代表與 Broker 的 TCP 連接,線程安全,開銷大,應共享複用。connection.start() 啟動消息分發,connection.stop() 暫停。
// 參數:transacted(是否事務)、acknowledgeMode(確認模式) Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
事務模式:transacted=true,多條收發打包為原子單位,session.commit()/rollback()。
確認模式(非事務時生效):
AUTO_ACKNOWLEDGE:自動確認(默認)CLIENT_ACKNOWLEDGE:手動 message.acknowledge(),精確控制DUPS_OK_ACKNOWLEDGE:延遲批量確認,允許重複,高吞吐SESSION_TRANSACTED:事務模式隱含確認MessageProducer producer = session.createProducer(queue); MessageConsumer consumer = session.createConsumer(topic);
TextMessage:JSON/XML/文本BytesMessage:二進制流MapMessage:鍵值對ObjectMessage:Java 序列化對象(慎用,跨語言不兼容)StreamMessage:原始類型流@Configuration
@EnableJms
public class JmsConfig {
@Bean
public ActiveMQConnectionFactory connectionFactory() {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
factory.setTrustedPackages(Arrays.asList("com.example.model"));
return factory;
}
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory cf) {
JmsTemplate template = new JmsTemplate(cf);
template.setDefaultDestinationName("order.queue");
template.setDeliveryPersistent(true);
return template;
}
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory cf) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(cf);
factory.setConcurrency("5-20"); // 消費者線程池
factory.setSessionTransacted(true); // 事務模式
factory.setSessionAcknowledgeMode(Session.SESSION_TRANSACTED);
return factory;
}
}
@Service
public class OrderService {
@Autowired private JmsTemplate jmsTemplate;
public void sendOrder(Order order) {
jmsTemplate.convertAndSend("order.queue", order, message -> {
message.setJMSCorrelationId(UUID.randomUUID().toString());
message.setJMSType("ORDER_CREATED");
return message;
});
}
}
@Component
public class OrderConsumer {
@JmsListener(destination = "order.queue", containerFactory = "jmsListenerContainerFactory")
public void onOrder(Order order, @Header(JmsHeaders.CORRELATION_ID) String correlationId) {
try {
processOrder(order);
} catch (Exception e) {
// 拋出異常觸發事務回滾、消息重試、最終進入 DLQ
throw new RuntimeException("Order processing failed", e);
}
}
}
DeliveryMode.PERSISTENT,Broker 寫磁盤,防宕機丟失JMSCorrelationID 或業務 ID 去重,應對重複投遞JMSPriority (0-9),緊急業務優先處理JMSExpiration 或 Broker 專用延遲隊列插件| 產品 | 協議支持 | 特點 | 適用場景 |
|---|---|---|---|
| ActiveMQ / Artemis | JMS, AMQP, MQTT, STOMP, OpenWire | 成熟、功能全、嵌入式部署易 | 傳統企業應用、中小規模 |
| RabbitMQ | AMQP 0-9-1 (需插件支持 JMS) | 高性能、靈活路由、集群優秀 | 微服務異步通信、事件驅動 |
| Apache Kafka | 自有協議 (Kafka Connect 支持 JMS Source/Sink) | 高吞吐、日志存儲、流處理 | 大數據管道、事件溯源、审計日志 |
| RocketMQ | 自有協議 (支持 JMS 1.1 部分特性) | 金融級可靠、分布式事務、順序消息 | 電商交易、金融核心系統 |
JMS 作為 Java 異步通信的標準化抽象,其核心價值在於 解耦生產者與消費者、屏蔽中間件差異、提供企業級可靠性語義。掌握兩大模型選型、編程模型對象職責、Spring 整合最佳實踐、可靠性模式組合,是構建高可用、可擴展分布式系統的必備技能。現代架構中,雖然直接使用 JMS API 較少(多封裝於 Spring Cloud Stream、RocketMQ Spring Boot Starter 等),但理解其底層原理對於故障排查、性能調優、架構決策至關重要。