消息大小
消息大小
Camel 可以在端点级别跟踪消息负载(正文和标头)的大小。这对可观测性很有用——可以了解消息有多大、检测负载膨胀,以及监控大小随时间的变化趋势。尺寸会按端点分别跟踪,涵盖传入(IN)和传出(OUT)两个方向。
消息大小跟踪默认关闭,必须显式启用。同时还需要扩展的管理统计级别。
| 消息大小跟踪是一个全局功能。启用后,它将应用于 CamelContext 中的所有端点。无法按路由或按端点进行细粒度的启用或禁用控制。 |
|---|
流式消息正文(例如 InputStream)只有在启用流缓存时才受支持。没有流缓存时,无法确定流式负载的正文大小,将报告为 -1(未知)。 |
|---|
工作原理
启用后,Camel 使用 RuntimeEndpointRegistry 事件机制计算消息正文和标头的大小:
- IN 方向 —— 当消费者端点创建 Exchange 时计算大小(例如,HTTP 请求到达、文件被消费、收到 JMS 消息)。计算出的大小还会作为 Exchange 属性(
CamelMessageBodySize和CamelMessageHeadersSize)存储,供路由过程中使用。 - OUT 方向 —— 当消息发送到生产者端点时计算大小(例如,发送到 Kafka 主题、写入文件、调用 HTTP 服务)。
尺寸统计信息(最小值、最大值、平均值)按端点收集,并作为运行时端点统计信息的一部分通过 JMX 暴露。
可插拔的 MessageSizeStrategy 负责计算实际大小。
启用消息大小
消息大小跟踪需要同时启用 messageSizeEnabled 选项和 Extended 统计级别:
- 应用属性
- Java
camel.main.messageSizeEnabled = true
camel.main.jmxManagementStatisticsLevel = ExtendedCamelContext context = ...
context.setMessageSize(true);
context.getManagementStrategy().getManagementAgent()
.setStatisticsLevel(ManagementStatisticsLevel.Extended);使用 dev profile 运行时会自动启用消息大小跟踪。 |
|---|
你可以在命令行中运行 Camel CLI:camel doc main --filter=messageSize,以查看消息大小相关的选项。 |
|---|
默认大小计算
默认的 MessageSizeStrategy 使用针对各类型的特定逻辑计算消息体大小。如果无法识别消息体的类型,则回退到 Content-Length 请求头(对于消息体是流的 HTTP 组件而言,这很有用)。如果无法确定大小,则返回 -1,且该 Exchange 不会被纳入大小统计。
消息体大小
| 消息体类型 | 大小计算方式 |
|---|---|
null | 0 |
byte[] | 数组长度 |
String | UTF-8 编码后的字节长度 |
StreamCache | length() 方法 |
WrappedFile | getFileLength() 方法(涵盖文件、FTP 等类似组件) |
File | length() 方法 |
Path | Files.size() |
Content-Length 请求头 | 回退方案:使用 Content-Length 消息请求头的值 |
其他 | -1(未知,不进行跟踪) |
请求头大小
请求头总大小通过遍历所有消息请求头并对以下内容求和得到:
- 每个请求头键的 UTF-8 字节长度
- 每个请求头值经
toString()转换后的 UTF-8 字节长度
如果没有请求头,则返回 0。
通过 JMX 获取端点统计信息
当启用 JMX 且统计级别设置为 Extended 时,大小统计信息会与现有的端点命中次数一起,显示在运行时端点注册表 MBean 中。
这些统计数据是 RuntimeEndpointRegistry MBean 上 endpointStatistics 表格数据的一部分(位于 org.apache.camel 域下,类型为 services):
| 列 | 说明 |
|---|---|
url | 端点 URI |
routeId | 关联的路由 ID |
direction | 消费者端点为 in,生产者端点为 out |
hits | 已处理的消息数量 |
minBodySize | 观察到的最小消息体大小(字节),未跟踪时为 -1 |
maxBodySize | 观察到的最大消息体大小(字节),未跟踪时为 -1 |
meanBodySize | 观察到的平均消息体大小(字节),未跟踪时为 -1 |
minHeadersSize | 观察到的最小头部总大小(字节),未跟踪时为 -1 |
maxHeadersSize | 观察到的最大头部总大小(字节),未跟踪时为 -1 |
meanHeadersSize | 观察到的平均头部总大小(字节),未跟踪时为 -1 |
当端点注册表的统计信息被重置时,这些统计信息也会被重置。
Exchange 属性
对于 IN 方向,计算出的大小可作为 exchange 属性在路由过程中使用。你可以将它们用于日志记录、基于内容的路由或自定义处理:
- Java
- XML
- YAML
from("seda:start")
.log("Body size: ${exchangeProperty.CamelMessageBodySize} bytes")
.choice()
.when(exchangeProperty("CamelMessageBodySize").isGreaterThan(1048576))
.to("direct:largeMessage")
.otherwise()
.to("direct:normalMessage");<route>
<from uri="seda:start"/>
<log message="Body size: ${exchangeProperty.CamelMessageBodySize} bytes"/>
<choice>
<when>
<simple>${exchangeProperty.CamelMessageBodySize} > 1048576</simple>
<to uri="direct:largeMessage"/>
</when>
<otherwise>
<to uri="direct:normalMessage"/>
</otherwise>
</choice>
</route>- route:
from:
uri: seda:start
steps:
- log:
message: "Body size: ${exchangeProperty.CamelMessageBodySize} bytes"
- choice:
when:
- simple: "${exchangeProperty.CamelMessageBodySize} > 1048576"
steps:
- to:
uri: direct:largeMessage
otherwise:
steps:
- to:
uri: direct:normalMessage| 属性 | 说明 |
|---|---|
CamelMessageBodySize | 消息体大小(字节),未知时为 -1 |
CamelMessageHeadersSize | 所有消息头的总大小(字节) |
| 这些 Exchange 属性在消费者端点创建 Exchange 时被设置。它们反映的是路由所接收到的传入消息的大小。 |
|---|
自定义策略
你可以提供自定义的 MessageSizeStrategy 实现,以处理特殊的大小计算逻辑(例如,处理特定于应用的消息体类型):
CamelContext context = ...
context.setMessageSizeStrategy(new MyCustomMessageSizeStrategy());
context.setMessageSize(true);该策略必须实现 org.apache.camel.spi.MessageSizeStrategy 接口。
评论
登录后参与评论
KnowForge