架构

交换池

师成师成· 更新于 2026-09-28· 阅读 6 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Exchange 池化

路由引擎会维护每条消息的状态,跟踪消息的流转路径以及消息接下来的去向。路由引擎还负责处理错误、采集指标等复杂任务。在路由过程中的每个处理步骤,都会在堆上分配少量的 Java 对象。

正因这些路由簿记和处理工作,Apache Camel 在路由消息时需要少量的资源开销。

随着云计算的发展,工作负载被精确计量,Camel 也因此进行了一系列核心优化以降低开销。

池化对象以减少对象分配

被复用的最重要的对象是 org.apache.camel.Exchange 对象。该对象是承载消息的根对象,包含消息的载荷、标头、元数据及其他内容。

除了对 Exchange 进行池化之外,路由引擎使用的内部对象也会被池化和循环复用。这可以大幅减少 Camel 核心本身产生的对象分配。

实际的消息内容(载荷和标头)始终会产生对象分配,所使用的 Camel 组件及其第三方库也会产生对象分配。启用池化后,Camel 核心及其路由引擎的内存占用接近于零。

这一切听起来都很美好,那么有什么缺点呢?对象池化的代价在于管理池的复杂性(从池中获取对象以及将对象归还给池)。不过,这些都由 Camel 自动处理。对象池使用 JDK 的 ConcurrentMap 实例,占用的内存非常少。管理池会带来少量的 CPU 开销,包括向池中添加和移除对象,以及在复用前重置对象。

在大多数情况下,用极小的 CPU 成本换取对象分配的减少是值得的。这可以避免 JVM 垃圾回收更频繁地运行,从而提高响应速度并降低延迟(在某些情况下,垃圾回收开销会导致应用程序因“停止世界”暂停及其相关的处理开销而暂停或延迟处理消息)。

启用 Exchange 池化

对象池化目前默认是禁用的。如果你使用的是 Camel Main(来自 Camel Core)、Camel Spring Boot 或 Camel Quarkus,可以在 application.properties 中启用它:

camel.main.exchange-factory = pooled

以编程方式启用 Exchange 池化

如果你使用的是其他运行时,或者希望以编程方式完成此操作,可以通过 ExtendedCamelContext 的 setExchangeFactory 方法来实现。以下是使用 Java 实现的示例:

// suppose a Camel context object declared in the scope
CamelContext context = ...

context.getCamelContextExtension().setExchangeFactory(new PooledExchangeFactory());
ExtendedCamelContext 是 Camel 的内部 API,因此它可能无法提供与公共 API 相同级别的向后兼容性。请尽可能通过应用属性来配置交换池。

配置选项

你可以使用以下选项配置交换池:

选项说明默认值
exchange-factory是否使用池。可选值为 prototype 或 pooledprototype
exchange-factory-capacity池中元素的最大数量100
exchange-factory-statistics-enabled是否收集使用统计信息false

管理

如果启用了对象池,Camel 会提供一个 JMX MBean,允许我们通过 JMX 检视这些池及其使用情况。这需要将 camel-management JAR 添加到类路径中。

示例

我们提供了一些用于性能剖析的示例。如果你需要一个示例,可以查看基础的 timer-log。

评论

登录后参与评论

正在加载评论…