本文介绍如何将Java应用的可观测数据投递至云数据库 ClickHouse 企业版,并通过一站式可观测服务进行分析,旨在帮助开发者和运维人员实时监控应用性能、提升问题解决效率。
前提条件
云数据库 ClickHouse 企业版实例已开启一站式可观测服务。
操作步骤
本文示例中,将在同一台ECS上部署业务服务和Otel Collector。生产环境下,建议独立部署业务服务和Otel Collector。
步骤一:部署Otel Collector
配置ECS实例。
购买ECS实例。建议购买时分配公网IP,使ECS具备公网访问能力。
将ECS IP地址添加到云数据库ClickHouse的白名单中。
私网IP:如果ECS实例与云数据库 ClickHouse 企业版实例位于同一VPC,可以将ECS的私网IP地址添加到白名单中,以下操作中云数据库ClickHouse实例的Endpoint使用VPC地址。
公网IP:如果ECS实例与云数据库 ClickHouse 企业版实例私网不通,可以将ECS的公网IP地址添加到白名单中,以下操作中云数据库ClickHouse实例的Endpoint使用外网地址。
您可以连接ECS实例,使用以下命令测试ECS与云数据库ClickHouse实例之间的连通性,若返回
Ok.代表连接正常。curl http://cc-xxxxxxx-clickhouse.clickhouseserver.pre.rds.aliyuncs.com:8123
连接ECS实例,依次执行以下命令,安装otelcol-contrib。
mkdir llm-demo cd llm-demo wget -O otelcol-contrib.rpm https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.136.0/otelcol-contrib_0.136.0_linux_amd64.rpm yum install otelcol-contrib.rpm配置Otel Collector,允许通过grpc和http协议接收可观测数据,并通过http协议投递至云数据库ClickHouse实例。
复制以下命令并修改相关配置:
在receivers区域:建议将otlp receiver的endpoint替换为Otel Collector服务的endpoint。
在exporters区域:
配置云数据库ClickHouse实例的连接信息,包括endpoint、username和password。
配置云数据库ClickHouse实例存储可观测数据的库名和表名,包括database、traces_table_name、logs_table_name和metrics_tables。
cat > /etc/otelcol-contrib/config.yaml << EOF receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 processors: batch: timeout: 5s send_batch_size: 5000 exporters: clickhouse: endpoint: http://cc-xxxxxx-clickhouse.clickhouseserver.pre.rds.aliyuncs.com:8123?dial_timeout=10s&compress=lz4&async_insert=1 username: test password: password # ttl: 72h traces_table_name: otel_traces logs_table_name: otel_logs metrics_tables: gauge: name: otel_metrics_gauge sum: name: otel_metrics_sum summary: name: otel_metrics_summary histogram: name: otel_metrics_histogram exponential_histogram: name: otel_metrics_exp_histogram create_schema: false timeout: 5s database: clickobserve_service sending_queue: queue_size: 1000 retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 300s service: pipelines: traces: receivers: [otlp] processors: [batch] exporters: [clickhouse] metrics: receivers: [otlp] processors: [batch] exporters: [clickhouse] logs: receivers: [otlp] processors: [batch] exporters: [clickhouse] EOF启动Otel Collector。
service otelcol-contrib restart
步骤二:创建Java应用
本节以一个简单的Springboot随机掷骰子服务为例,介绍应用创建过程。
配置Java环境。
本示例目录命名为
java-simple,初始化后目录结构参见下方:java-simple ├── app │ ├── build.gradle.kts │ └── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └── example │ │ │ └── App.java │ │ └── resources │ └── test │ ├── java │ │ └── org │ │ └── example │ │ └── AppTest.java │ └── resources ├── gradle │ ├── libs.versions.toml │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts在
java-simple目录下修改或创建以下文件:修改build.gradle.kts
plugins { id("java") id("org.springframework.boot") version "3.0.6" id("io.spring.dependency-management") version "1.1.0" } sourceSets { main { java.setSrcDirs(setOf(".")) } } repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-web") }修改App.java
package org.example; import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication app = new SpringApplication(App.class); app.setBannerMode(Banner.Mode.OFF); app.run(args); } }新建RollController.java
package org.example; import java.util.Optional; import java.util.concurrent.ThreadLocalRandom; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class RollController { private static final Logger logger = LoggerFactory.getLogger(RollController.class); @GetMapping("/rolldice") public String index(@RequestParam("player") Optional<String> player) { int result = this.getRandomNumber(1, 6); if (player.isPresent()) { logger.info("{} is rolling the dice: {}", player.get(), result); } else { logger.info("Anonymous player is rolling the dice: {}", result); } return Integer.toString(result); } public int getRandomNumber(int min, int max) { return ThreadLocalRandom.current().nextInt(min, max + 1); } }
步骤三:配置OpenTelemetry Java Agent
下载OpenTelemetry Java Agent。
curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar配置环境变量。
export JAVA_TOOL_OPTIONS="-javaagent:/../opentelemetry-javaagent.jar" \ OTEL_TRACES_EXPORTER=otlp \ OTEL_METRICS_EXPORTER=otlp \ OTEL_LOGS_EXPORTER=otlp \ OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \ OTEL_EXPORTER_OTLP_ENDPOINT=http://<IP地址>:4318 \ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://<IP地址>:4318/v1/traces \ OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<IP地址>:4318/v1/metrics \ OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://<IP地址>:4318/v1/logs \ OTEL_METRIC_EXPORT_INTERVAL=15000JAVA_TOOL_OPTIONS:修改为Java Agent的实际存放路径。Endpoint相关配置:
http://<IP地址>:4318中的IP地址,为Java应用可访问的Otel Collector服务端点。其他参数选择,请参见properties-exporters。
步骤四:启动并访问Java应用
在项目应用目录下依次执行以下命令,启动应用。
在本示例中,项目应用目录为
../java-simple/app。gradle assemble java -jar ./build/libs/app.jar浏览器访问
http://<IP地址>:8080/rolldice,IP地址为运行Java应用的服务器IP地址。
步骤五:查询与分析可观测数据
在云数据库ClickHouse实例详情页左侧导航栏单击一站式可观测,根据页面提示前往服务入口。
在主页面上查询并分析Java应用的可观测数据。
