大家好,我是G探险者!
系列文章的第 5 篇,本篇将聚焦在 发送端的连接池机制,也就是大家在使用 JmsTemplate 发送消息时最常见但容易忽略的问题 —— 是否使用了 CachingConnectionFactory。
📌 引入场景
你是否遇到过这样的问题:
- 用
JmsTemplate发送消息,第一次成功,第二次就抛连接异常? - 每次发送消息都重新连接 MQ,发送延迟很高?
- MQ 重启后,监听可以恢复,发送却彻底挂死?
这背后的根本原因是:
你直接用了原始的
ConnectionFactory而没有加上连接池管理。
✅ 一、ConnectionFactory 和 CachingConnectionFactory 是什么?
1️⃣ ConnectionFactory(原始)
- 来自 JMS 标准(
javax.jms.ConnectionFactory) - 每次创建连接都是真实连接
- 不具备自动重连、连接复用、Session 缓存能力
2️⃣ CachingConnectionFactory(Spring 提供)
- 包装一个原始的 JMS
ConnectionFactory - ✅ 重用连接(默认只有一个连接)
- ✅ 支持 session 缓存(提升性能)
- ✅ 支持重连恢复(底层连接失效时自动重建)
⚙️ 二、配置示例:推荐使用方式
// 原始 MQ 连接工厂(IBM MQ 示例)
MQQueueConnectionFactory rawFactory = new MQQueueConnectionFactory();
rawFactory.setHostName("192.168.1.100");
rawFactory.setPort(1414);
rawFactory.setQueueManager("QM1");
rawFactory.setChannel("CHANNEL1");
rawFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
// 使用 Spring 的缓存连接工厂进行包装
CachingConnectionFactory cachingFactory = new CachingConnectionFactory(rawFactory);
// ✅ 可选设置缓存 session 数量
cachingFactory.setSessionCacheSize(10);
// 创建 JmsTemplate
JmsTemplate jmsTemplate = new JmsTemplate(cachingFactory);
📊 三、对比分析
| 功能点 | 原始 ConnectionFactory | CachingConnectionFactory |
|---|---|---|
| 每次连接是否复用 | ❌ 否,每次都新建 | ✅ 是,复用同一个连接 |
| 是否支持自动重连 | ❌ 否 | ✅ 是(连接断开后自动恢复) |
| Session 是否缓存 | ❌ 否 | ✅ 是(默认缓存一个) |
| 性能表现 | ⛔️ 低,大量连接开销 | ✅ 高,复用连接和 session |
| 使用场景 | 调试、非常简单应用 | ✅ 生产强烈推荐 |
🔁 四、消息发送中的连接复用机制
JmsTemplate 每次发送消息的流程大致如下:
→ 从 ConnectionFactory 获取连接
→ 创建 Session
→ 创建 Producer
→ 发送消息
→ 关闭资源(除非有缓存)
若使用 CachingConnectionFactory:
- 第一步中,连接将被复用
- 第二步中,session 会被从缓存中取出或复用
- 避免每次都连接 MQ,极大提升性能
🧯 五、发送端的重连机制:和监听端不同!
| 对象 | 重连机制靠谁维护? |
|---|---|
DefaultMessageListenerContainer | Spring 内部有自动重连逻辑 |
JmsTemplate | ❌ 没有内建重连机制,依赖底层连接工厂 |
因此:
若你使用原始
ConnectionFactory,一旦 MQ 重启,发送端将直接挂死!
只有使用 CachingConnectionFactory,它才会在连接失败时尝试自动重建连接,保证长时间可用性。
⚠️ 六、一些开发误区
| 误区 | 正确做法 |
|---|---|
JmsTemplate 能自动帮我处理连接 | ❌ 不行,必须自己包装连接工厂 |
| 使用事务就能保证可靠发送 | ❌ 发送失败了都不会 retry,要靠连接池重连 |
| MQ 能自动恢复连接 | ❌ 不在发送端,需要 CachingConnectionFactory |
☑️ 七、总结建议
| 场景 | 推荐配置 |
|---|---|
使用 JmsTemplate 发送消息 | ✅ 使用 CachingConnectionFactory |
| 发送性能要求高 | ✅ 设置 sessionCacheSize ≥ 并发数 |
| 需要自动重连 | ✅ CachingConnectionFactory 自动支持 |
| 一定要避免每次连接创建开销 | ❗ 千万不要直接使用裸 ConnectionFactory |
📘 下一篇预告:
第 6 篇:《JMS 中的事务机制与消息确认模式全解:AUTO_ACK、CLIENT_ACK、SESSION_TRANSACTED 有啥区别?》
我们将系统讲解 JMS 的 4 种消息确认模式,事务控制与 ACK 的关系,以及在 Spring 中如何灵活切换并掌握失败处理策略。