如何调试哪个特定的 Camel Route 有一种 "CPU leak"?每条路线是否有 CU 指标?

How to debug which particular Camel Route has a kind of "CPU leak"? Is there a CU metrics per route?

我们 运行 在我们的 Camel 实例上有一堆非常不同的数据抓取路线。而在 Camel 启动后大约 1 周 运行,Camel 占用的 CPU 资源趋于增长并且永远不会被释放:

当它们达到 100% 时,开始发出声音,我们错过了数据。

第一个也是非常简单的方法是设置 1 个实例,并在 1 个实例中保留唯一的路由以供观察,而其余的则在另一个实例中,直到我们定义哪个导致问题然后在这条特定路线中调试一些 points/beans 。但是由于降级需要一周的时间,所以这种方法看起来很慢。

是否有一种 CPU-per-route 指标可以让我们估计哪条路由消耗了 CPU 资源?

UPD:我也在监控路由指标,但不幸的是,每条路由的指标 s 只是给我计时,h 没有发散并且看起来 increasing/go peaking/go 同时振荡。

sum by(routeId)(rate(CamelMessageHistory_seconds_sum{}[5m]))

rate(label_replace({__name__=~"camel_proxy.*count"},"name_label","","__name__", "(.+)")[5m:])

被绘制成这样的 Micrometer 指标:

# HELP CamelRoutePolicy_seconds_max  
# TYPE CamelRoutePolicy_seconds_max gauge
CamelRoutePolicy_seconds_max{camelContext="camel-1",failed="false",routeId="realtime_positioning_raw",serviceName="MicrometerRoutePolicyService",} 1.3250687
# HELP CamelRoutePolicy_seconds  
# TYPE CamelRoutePolicy_seconds summary
CamelRoutePolicy_seconds_count{camelContext="camel-1",failed="false",routeId="realtime_positioning_raw",serviceName="MicrometerRoutePolicyService",} 868.0
CamelRoutePolicy_seconds_sum{camelContext="camel-1",failed="false",routeId="realtime_positioning_raw",serviceName="MicrometerRoutePolicyService",} 15.7921739

# HELP camel_proxy_mqtt_kafka_stream_seconds  
# TYPE camel_proxy_mqtt_kafka_stream_seconds summary
camel_proxy_mqtt_kafka_stream_seconds_count{camelContext="camel-1",} 868.0
camel_proxy_mqtt_kafka_stream_seconds_sum{camelContext="camel-1",} 14.5903913
# HELP camel_proxy_mqtt_kafka_stream_seconds_max  
# TYPE camel_proxy_mqtt_kafka_stream_seconds_max gauge
camel_proxy_mqtt_kafka_stream_seconds_max{camelContext="camel-1",} 1.297158

您可以使用 VisualVM (https://visualvm.github.io/) 对您的应用程序进行采样或分析,您会发现使用 CPU.

的方法

使用 camel 可以添加 hawtio (https://hawt.io/),它可以提供帮助。

假设您使用的是 Camel 3.x,我建议您做两件事:

  1. 激活 MicroProfile 指标,以便您可以分析 Camel 内置路由指标(通过调用 Web 服务返回非 Prometheus 格式的数据)

  2. 启用交换池以减少对象分配

这是一个关于如何在 CDI 环境中执行此操作的示例

public class CamelSupport {

    @Inject
    private MetricRegistry metricRegistry;


    @Produces
    @ApplicationScoped
    public final CamelContext createContext() {
        CdiCamelContext context = new CdiCamelContext();
        context.setName("demo");
        ...
        MicroProfileMetricsRoutePolicyFactory mpmrp = new MicroProfileMetricsRoutePolicyFactory();
        mpmrp.setMetricRegistry(metricRegistry);
        context.addRoutePolicyFactory(mpmrp); // (1)

        
        context.setExchangeFactory( new PooledExchangeFactory() ); // (2)
        return context;
    }