无需JMX,Java程序捕获Cassandra集群Dropwizard Metrics技术咨询
嗨,作为Java新手能关注到Cassandra的指标收集,这点很棒!我来帮你梳理下怎么用原生Dropwizard Metrics API来实现你的需求~
原生Dropwizard Metrics API的支持情况
Cassandra本身就是基于Dropwizard Metrics来实现内部指标统计的,所以完全存在原生API可以直接获取这些指标,不需要通过JMX。你可以直接访问Cassandra内部的MetricRegistry实例,就能拿到所有的指标数据,然后自行处理成JSON格式发送到其他服务器。
获取指标的Java示例代码
下面给你一个完整的示例,包含获取单个指定指标、将所有指标转为JSON的操作:
1. 依赖准备
首先要确保你的项目中包含对应的依赖(以Maven为例):
<dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-json</artifactId> <version>4.2.22</version> <!-- 版本需匹配你的Cassandra所用的Metrics版本,建议查Cassandra官方文档确认 --> </dependency> <dependency> <groupId>org.apache.cassandra</groupId> <artifactId>cassandra-all</artifactId> <version>4.1.3</version> <!-- 替换成你的Cassandra版本 --> <scope>provided</scope> <!-- 如果是在Cassandra节点上运行该程序,用provided避免依赖冲突 --> </dependency>
2. 代码实现
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Histogram; import com.codahale.metrics.json.MetricsModule; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.cassandra.config.DatabaseDescriptor; import java.util.concurrent.TimeUnit; public class CassandraMetricsCollector { public static void main(String[] args) { // 第一步:获取Cassandra的MetricRegistry核心实例,这是所有指标的入口 MetricRegistry metricRegistry = DatabaseDescriptor.getMetricRegistry(); // 示例1:获取单个特定指标(以读请求延迟的直方图为例) String targetMetricName = "org.apache.cassandra.metrics.ClientRequest.Read.Latency"; if (metricRegistry.getMetrics().containsKey(targetMetricName)) { Histogram readLatencyHistogram = metricRegistry.histogram(targetMetricName); // 提取直方图的关键统计值:中位数、95分位、99分位 System.out.println("=== 单个指标详情 ==="); System.out.println("读请求延迟中位数: " + readLatencyHistogram.getSnapshot().getMedian()); System.out.println("读请求延迟95分位值: " + readLatencyHistogram.getSnapshot().get95thPercentile()); System.out.println("读请求延迟99分位值: " + readLatencyHistogram.getSnapshot().get99thPercentile()); } else { System.out.println("目标指标不存在,请检查指标名称是否正确"); } // 示例2:将所有指标转换为JSON格式,方便发送到其他服务器 System.out.println("\n=== 所有指标JSON格式输出 ==="); // 初始化ObjectMapper并注册Metrics的JSON模块,指定时间单位 ObjectMapper objectMapper = new ObjectMapper() .registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, false)); try { // 将整个MetricRegistry序列化为JSON字符串 String metricsJson = objectMapper.writeValueAsString(metricRegistry); System.out.println(metricsJson); // 这里可以添加代码将metricsJson发送到目标服务器,比如用HttpURLConnection、RestTemplate等工具 // 示例(伪代码): // HttpClient httpClient = HttpClient.newHttpClient(); // HttpRequest request = HttpRequest.newBuilder() // .uri(URI.create("http://your-alert-server/metrics")) // .header("Content-Type", "application/json") // .POST(HttpRequest.BodyPublishers.ofString(metricsJson)) // .build(); // HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); } catch (Exception e) { System.err.println("转换JSON或发送请求时出错: " + e.getMessage()); e.printStackTrace(); } } }
额外说明
- 如果你是通过Cassandra Java Driver连接集群(而非在Cassandra节点上运行程序),那么可以通过Driver的Metrics注册表来获取客户端侧的指标,示例代码如下:
// 新Driver(4.x+)的方式 CqlSession session = CqlSession.builder().build(); MetricRegistry driverMetricRegistry = session.getMetrics().getRegistry(); // 后续操作和上面的示例一致 - 你可以通过
metricRegistry.getMetrics().keySet()打印所有可用的指标名称,来确认你需要捕获的指标的准确名称 - 发送JSON到其他服务器时,记得处理异常情况,比如网络超时、目标服务器不可达等
内容的提问来源于stack exchange,提问作者Vishal Sharma
相关产品推荐
相关产品推荐

