Ohhnews

分类导航

$ cd ..
Baeldung原文

Apache Camel 可观测性服务配置指南

#apache camel#可观测性#java#分布式追踪#系统监控

[LOADING...]

1. 简介

Apache Camel 是一个基于 Java 的集成框架,它实现了企业集成模式(EIP)。

在本文中,我们将演示如何使用 Apache Camel 的可观测性相关组件来监控应用程序的健康状况和性能。

2. Maven 依赖

该应用程序的两种变体(Spring Boot 和 Standalone)使用不同的工具来发送跨度(Span)和追踪(Trace)。因此,有必要分别列出它们的依赖项。

2.1. Spring Boot

首先,对于 Spring Boot 示例,我们需要定义 spring-boot-startercamel-spring-boot-starterspring-boot-starter-actuatorcamel-observation-startermicrometer 以及 zipkin 的依赖:

$ xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>3.5.11</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.5.11</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel.springboot</groupId>
        <artifactId>camel-spring-boot-starter</artifactId>
        <version>4.18.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <version>3.5.11</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        <version>3.5.11</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel.springboot</groupId>
        <artifactId>camel-observation-starter</artifactId>
        <version>4.18.0</version>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing</artifactId>
        <version>1.5.0</version>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-brave</artifactId>
        <version>1.5.0</version>
    </dependency>
    <dependency>
        <groupId>io.zipkin.reporter2</groupId>
        <artifactId>zipkin-reporter-brave</artifactId>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
        <version>1.5.0</version>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-core</artifactId>
        <version>1.15.9</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.5.32</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.5.32</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

对于 Spring Boot 变体,应用程序使用 Micrometer 生成观测数据,随后由 micrometer-tracing-bridge-brave 转换为 Brave 跨度。接着,zipkin-reporter-brave 将转换后的跨度发送到 Zipkin 后端(在本例中为 Jaeger)。最后,spring-boot-actuator-autoconfigure 依赖项通过配置和实例化将跨度发送到 Jaeger 的组件,将所有内容整合在一起。

2.2. Camel Standalone

同样,对于 Camel Standalone 应用程序监控,我们需要 camel-corecamel-maincamel-observability-servicescamel-opentelemetry2

$ xml
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-core</artifactId>
    <version>4.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-main</artifactId>
    <version>4.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-observability-services</artifactId>
    <version>4.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-opentelemetry2</artifactId>
    <version>4.17.0</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.5.29</version>
    <scope>compile</scope>
</dependency>

在此版本中,camel-observability-services 依赖项提供了用于导出追踪和健康指标的预配置组件。在示例中,我们使用 OpenTelemetry Java 代理将追踪发送到 Jaeger。

3. 被监控的应用程序

现在,让我们确保有一个用于观测的对象。首先,我们创建一个从目录读取 XML 文件、通过添加当前时间戳进行处理并将它们复制到另一个目录的应用程序

在 Camel 应用程序中,路由(Routes)定义了数据如何被处理,而 RouteBuilder 接口使我们能够使用 Java-DSL 配置应用程序路由。在创建 RouteBuilder 之前,我们先编写 SimpleProcessor,它将被 RouteBuilder 使用,并且在两种应用程序变体中完全相同:

$ java
public class SimpleProcessor implements Processor {
    private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newDefaultInstance();
    @Override
    public void process(Exchange exchange) throws Exception {
        String body = exchange.getMessage().getBody(String.class);
        String processedAt = LocalDateTime.now().toString();
        InputStream stream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
        Document document = factory.newDocumentBuilder().parse(stream);
        Element root = document.getDocumentElement();
        Element newElemeent = document.createElement("processed");
        newElemeent.setTextContent(processedAt);
        root.appendChild(newElemeent);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        StringWriter stringWriter = new StringWriter();
        transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
        String newBody = stringWriter.toString();
        exchange.getMessage().setBody(newBody);
    }
}

有了处理器之后,现在是时候编写 RouteBuilder 组件了,除了依赖注入代码外,它对于 Spring Boot 和 Standalone 应用程序几乎是一样的。Spring Boot 的 RouteBuilder(名为 SimpleRouteBuilder)使用了构造函数注入:

$ java
public class SimpleRouteBuilder extends RouteBuilder {
    private final SimpleProcessor simpleProcessor;
    @Autowired
    public SimpleRouteBuilder(SimpleProcessor simpleProcessor) {
        this.simpleProcessor = simpleProcessor;
    }
    public void configure() {
        from("file://src/data?noop=true")
          .choice()
          .when(xpath("/person/city = 'London'"))
            .log("UK message")
            .to("file:target/messages/uk")
            .log("UK message 2")
            .process(simpleProcessor)
            .to("file:target/messages/general-sink")
          .otherwise()
            .log("Other message")
            .to("file:target/messages/others")
            .log("Other message 2")
            .process(simpleProcessor)
            .to("file:target/messages/general-sink");
    }
}

对于 Standalone 应用程序的 RouteBuilder,我们使用 @BeanInject 注解,它从 Camel Registry 中注入一个已注册的组件:

$ java
public class SimpleRouteBuilder extends RouteBuilder {
    @BeanInject("SimpleProcessor")
    SimpleProcessor simpleProcessor;
// 文件其余部分与 Spring Boot 的 SimpleRouteBuilder 相同

最后,我们实现将所有部分整合在一起的应用程序。首先编写带有 @SpringBootApplication 注解的主类:

$ java
@CamelObservation
@SpringBootApplication
public class CamelSpringBootApplication {
	public static void main(String[] args) {
            SpringApplication.run(FirstCamelSpringBootApplication.class, args);
	}
	@Bean
	SimpleProcessor simpleProcessor() {
	    return new SimpleProcessor();
	}
	@Bean
	SimpleRouteBuilder simpleRouteBuilder(SimpleProcessor simpleProcessor) {
	    return new SimpleRouteBuilder(simpleProcessor);
	}
}

CamelSpringBootApplication 类使用了 @CamelObservation 注解并定义了所需的 Spring Bean。此外,包含在 camel-observation-starter 依赖中的 @CamelObservation 注解配置了 Micrometer Observation,以生成 Camel 路由的指标和追踪

同样,在名为 MainApp 的 Standalone 应用程序中,我们使用 SimpleRouteBuilderSimpleProcessor 配置 Camel 上下文:

$ java
public class MainApp {
    public static void main(String... args) throws Exception {
        Main main = new Main();
        main.configure().addRoutesBuilder(new SimpleRouteBuilder());
        main.bind("SimpleProcessor", new SimpleProcessor());
        main.run(args);
    }
}

此外,为了执行 MainApp.main() 方法,我们配置了 camel-maven-plugin

$ xml
<plugin>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-maven-plugin</artifactId>
    <version>3.18.4</version>
    <configuration>
        <logClasspath>true</logClasspath>
        <mainClass>com.baeldung.camel.observability.MainApp</mainClass>
    </configuration>
</plugin>

确实,camel-maven-plugin 使我们能够通过执行简单的 mvn 命令来启动 Camel Standalone 应用程序:

$ bash
mvn camel:run

此外,让我们通过 application.yml 中的配置属性启用 opentelemetry2 组件:

$ config
camel:
  opentelemetry2:
    enabled: true
    trace-processors: true
    trace-headers-inclusion: true

最后,为了确保报告每一次应用程序交互,还需要调整采样概率:

$ config
management:
  tracing:
    sampling:
      probability: 1.0

另一方面,Standalone 变体只需要启用 opentelemetry2

$ properties
camel.opentelemetry2.enabled=true

这样,我们就准备好进行监控了。

4. 监控设置与展示

为了方便起见,我们可以在 Jaeger 服务器上监控两种应用程序变体的追踪数据。

4.1. Jaeger 部署

让我们将 Jaeger 服务器部署为 Docker 容器:

$ bash
docker run --name jaeger -p 16686:16686 -p 4317:4317 -p 4318:4318 -p 5778:5778 -p 9411:9411 cr.jaegertracing.io/jaegertracing/jaeger:2.15.0

通过这种方式,我们可以在无需手动设置的情况下获得一个可用的部署。

4.2. Spring Boot

Spring Boot 应用程序监控无需额外步骤,因此我们启动应用程序:

$ bash
mvn spring-boot:run

现在,导航到 Jaeger 的仪表板以查找追踪数据。仪表板 URL 为 *http://localhost:16686*。要查找相关的追踪,我们使用应用程序名称作为服务过滤器,使用 file 作为操作过滤器:

[LOADING...]

随后,通过点击并展开第一个追踪,我们可以详细检查其内容:

[LOADING...]

嵌套的跨度包含了各个文件操作:

[LOADING...]

再次强调,所有这些功能都是我们所使用依赖项的开箱即用行为。

4.2. Standalone

为了启用 Standalone 应用程序的追踪功能,我们使用略有不同的 mvn 命令,以便 opentelemetry-java 代理将追踪发送到 Jaeger:

$ bash
MAVEN_OPTS="-javaagent:path/to/opentelemetry-javaagent.jar -Dotel.service.name=camel-standalone" mvn camel:run

在 Jaeger 仪表板中,我们使用 Camel Standalone 应用程序名称作为服务过滤器的值:

[LOADING...]

正如预期的那样,Camel Standalone 应用程序的跨度内容与 Spring Boot 应用程序的跨度没有区别。

5. 结论

在本文中,我们演示了如何配置 Camel 应用程序以生成追踪并将其发送到 Jaeger 服务器。

具体来说,我们提供了 Spring Boot 和 Camel Standalone 两种应用程序的示例,以确保两者之间的有效对比。

总之,通过正确的设置,无论应用程序架构如何,使用 Apache Camel 都是监控应用程序的一种相当简单直接的方法。