交换池
路由引擎会记录每条信息的状态,跟踪信息流以及信息的下一步去向。路由引擎还能处理复杂的任务,如错误处理、捕获度量指标等。在路由过程中,每个处理步骤都会在堆上分配少量 Java 对象。
由于这种路由簿记和处理,Apache Camel 在路由消息时需要极小的资源开销。
随着云计算的发展,工作负载被精确测量,Camel 也进行了一系列核心优化,以减少开销。
汇集对象以减少对象分配
最重要的重用对象是 org.apache.camel.Exchange
对象。该对象是根对象,包含信息及其有效载荷、标头、元数据和其他内容。
除了交换池,路由引擎使用的内部对象也会被池化和回收。这可以大大减少 Camel 内核本身的对象分配。
实际消息内容(有效载荷和标头)、使用中的 Camel 组件及其第三方库都会分配对象。启用池化后,Camel 内核及其路由引擎的占用空间几乎为零。
这一切听起来都很美妙,那么有什么负面影响呢?对象池的代价是管理对象池(获取对象并将其返回对象池)的复杂性。不过,所有这些都由 Camel 本身负责。对象池使用 JDK ConcurrentMap
实例,占用内存很少。管理对象池会产生少量 CPU 开销,这与从对象池中添加和删除对象以及在重用前重置对象有关。
在大多数情况下,可以牺牲极小的 CPU 成本来换取更少的对象分配。这可以防止 JVM 更频繁地运行垃圾回收,从而提高响应速度并减少延迟(在某些情况下,垃圾回收的开销可能会导致应用程序停止运行或延迟处理消息,因为会出现 "世界停顿"(stop-the-world)以及与之相关的其他处理开销)。
启用交换池
对象池目前默认为禁用。如果您使用的是 Camel Main(来自 Camel Core)、Camel Spring Boot 或 Camel Quarkus,则可以在 application.properties
.NET 中启用对象池功能:
camel.main.exchange-factory = pooled
在 camel 3.x 上启用交换池功能
如果您使用的是其他运行时,或希望以编程方式完成此操作,则可在 Camel 版本 3(Camel 3.x)中使用 ExtendedCamelContext
中的 setExchangeFactory
方法。.下面是一个使用 Java 的示例:
// suppose a Camel context object declared in the scope
CamelContext context = ...
context.adapt(ExtendedCamelContext.class).setExchangeFactory(new PooledExchangeFactory());
|
在 camel 4.x 上启用交换池功能
如果您使用的是不同的运行时,或者您想通过编程实现这一功能,那么在 Camel 4 及更新版本中,您可以使用 ExtendedCamelContext
中的 setExchangeFactory
方法来实现这一功能。.下面是一个使用 Java 的示例:
CamelContext context = ...
context.getExchangeExtension().setExchangeFactory(new PooledExchangeFactory());
|
配置选项
您可以使用以下选项配置 exchange poolomg:
选项 | 说明 | 默认值 |
---|---|---|
交换工厂 |
| 原型 |
|
| 100 |
exchange-factory-statistics-enabled |
| 错误 |