从 Tibco 主题(使用 tibjms 4.4.3 库)消费时,我在 Camel (2.10.3) 中看到一个非常奇怪的内存泄漏。从堆转储来看,内存消耗似乎是大量的 ConcurrentHashMap 东西(Segment、HashEntry[]、锁等)。
我认为正在发生的事情是,来自该主题的交流永远不会被 Camel 标记为“完整”,并且它会在内存中保留对它们的引用。当我将它们路由到“.stop()”时,问题就消失了。
我创建了一个 JMS 组件:
TibjmsConnectionFactory connectionFactory = new TibjmsConnectionFactory();
connectionFactory.setServerUrl(properties.getProperty(endpoints.getServerUrl()));
connectionFactory.setUserName(properties.getProperty(endpoints.getUsername()));
connectionFactory.setUserPassword(properties.getProperty(endpoints.getPassword()));
JmsComponent emsComponent = JmsComponent.jmsComponent(connectionFactory);
return emsComponent;
在上下文中注册它:
camelContext.addComponent("positionems", emsComponent);
然后创建了一个非常简单的测试路线来重现问题:
from("positionems:topic:UK.TOPIC4")
.to("mock:out");
有趣的是,这将用 ConcurrentHashMap 的东西填满堆,直到进程因堆空间错误而崩溃。但是,如果我将路线更改为:
from("positionems:topic:UK.TOPIC4")
.stop();
根据停止的 javadoc,它“停止继续路由当前的 org.apache.camel.Exchange 并将其标记为已完成。” - 大概“将其标记为已完成”是我将其发送到模拟时所缺少的(或者实际上当我运行完整的正常程序时,它的行为方式与将其发送到模拟的内存方式相同)。
我已经尝试了很多 Jms 路由配置的变体,例如:
from("positionems:topic:UK.TOPIC4?disableReplyTo=true&deliveryPersistent=false")
而且我已经尝试设置路线永远不会期望得到响应,但也许我做错了:
from("positionems:topic:UK.TOPIC4")
.inOnly() // marked as deprecated?
.to("mock:out");
这是 Tibco 特有的问题吗?鉴于使用 ActiveMQ 没有任何问题的人数,我很难相信我在 Camel 中发现了一个实际的错误,希望我做错了一些非常简单的错误!
编辑
我已经使用最新的 Camel 版本(2.12.1)进行了测试,这似乎要好一些(ConcurrentHashMap Segments 的数量增长较慢)但仍然绝对是一个问题。