sentinel prometheus指标收集及资源规则正则表达式实现

news/2024/5/19 0:03:44 标签: sentinel, prometheus, 正则表达式

sentinel__prometheus__0">sentinel 支持 prometheus 收集指标

实现原理

在这里插入图片描述

sentinel-extension 模块下,新增 sentinel-prometheus-metric-exporter 模块。依赖Prometheus 提供的 simpleclient 和 simpleclient_httpserver 来实现 exporter。
依赖 simpleclient 主要是为了实现自定义Collector:SentinelCollector, SentinelCollector 继承了抽象类 Collector,实现 collect 方法来获取指标样本数据。指标样本数据的获取是通过 MetricSearcher 对象读取 metrics.log 文件内容得到的。

metrics.log 文件内容,包含时间、资源名、通过 QPS、block QPS 等数据:

在这里插入图片描述
simpleclient_httpserver 主要用来实现一个简单的 HTTP 服务器,接收来自 Prometheus 获取指标数据的请求。
在这里插入图片描述

代码说明

public void init() throws Exception {
        HTTPServer server = null;
        try {
            // 注册自定义 Collector
            new SentinelCollector().register();
            // 开启http服务供prometheus调用
            // 默认只提供一个接口 http://ip:port/metrics,返回所有指标
            int promPort = PrometheusGlobalConfig.getPromFetchPort();
            server = new HTTPServer(promPort);
        } catch (Throwable e) {
            RecordLog.warn("[PromExporterInit] failed to init prometheus exporter with exception:", e);
        }

        HTTPServer finalServer = server;
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            if (finalServer != null) {
                finalServer.stop();
            }
        }));
    }

init 方法启动,先注册 SentinelCollector ,然后启动 HTTPServer 用于接收 prometheus 等请求。

public List<MetricFamilySamples> collect() {
        // 初始化指标读取对象
        if (searcher == null) {
            synchronized (lock) {
                if (searcher == null) {
                    searcher = new MetricSearcher(MetricWriter.METRIC_BASE_DIR,
                            MetricWriter.formMetricFileName(SentinelConfig.getAppName(), PidUtil.getPid()));
                }
                RecordLog.warn("[SentinelCollector] init sentinel metrics searcher with appName:{}", appName);
                lastFetchTime = System.currentTimeMillis() / ONE_SECOND * ONE_SECOND;
            }
        }

        List<MetricFamilySamples> list = new ArrayList<>();

        long endTime = System.currentTimeMillis() / ONE_SECOND * ONE_SECOND - (long) delayTime * ONE_SECOND;
        try {
            // 读取指标数据
            List<MetricNode> nodes = searcher.findByTimeAndResource(lastFetchTime, endTime, identify);
            if(nodes == null){
                return list;
            }
            if(nodes.size() > fetchSize){
                nodes = nodes.subList(0,fetchSize);
            }
            GaugeMetricFamily metricFamily = new GaugeMetricFamily(appName, MetricConstants.METRIC_HELP,
                    Arrays.asList(MetricConstants.RESOURCE, MetricConstants.CLASSIFICATION,
                            MetricConstants.METRIC_TYPE));
            for (MetricNode node : nodes) {
                // 转化成 prometheus 要求的指标数据模型
                long recordTime = node.getTimestamp();
                for (String type : types) {
                    double val = getTypeVal(node,type);
                    metricFamily.addMetric(Arrays.asList(node.getResource(), String.valueOf(node.getClassification()),type), val,recordTime);
                }
            }
            list.add(metricFamily);
        } catch (Exception e) {
            RecordLog.warn("[SentinelCollector] failed to fetch sentinel metrics with exception:", e);
        }finally {
            lastFetchTime = endTime + ONE_SECOND;
        }

        return list;
    }

SentinelCollector collect 方法实现具体的读取 metrics.log 文件逻辑。

sentinel__90">sentinel 支持资源规则正则表达式匹配

主要是通过增加 RuleManager 来统一管理普通规则和正则规则,为了减少正则解析/匹配所带来的性能损耗,增加了资源和匹配后的正则限流规则缓存,当获取资源规则时直接从Map 中读取缓存,避免每次都重新进行一次正则匹配。这是一种典型的空间换时间的做法。

另外在修改完规则后,更新时也会根据现有的缓存关系,重新构建新的缓存关系。

类图:
在这里插入图片描述

代码解析

    private Map<Pattern, List<R>> regexRules = new HashMap<>();
    // 缓存资源和对应的正则规则
    private Map<String, List<R>> regexCacheRules = new HashMap<>();
    private Map<String, List<R>> simpleRules = new HashMap<>();

获取规则

public List<R> getRules(String resource) {
        List<R> result = new ArrayList<>(simpleRules.getOrDefault(resource, Collections.emptyList()));
        if (regexRules.isEmpty()) {
            return result;
        }
        if (regexCacheRules.containsKey(resource)) {
            result.addAll(regexCacheRules.get(resource));
            return result;
        }
        synchronized (this) {
            if (regexCacheRules.containsKey(resource)) {
                result.addAll(regexCacheRules.get(resource));
                return result;
            }
            List<R> compilers = matcherFromRegexRules(resource);
            regexCacheRules.put(resource, compilers);
            result.addAll(compilers);
            return result;
        }
    }

引用参考

  1. https://github.com/alibaba/Sentinel/pull/3173
  2. https://github.com/alibaba/Sentinel/pull/3251
  3. https://prometheus.wang/exporter/client_library_java.html
  4. https://www.yuque.com/g/liushi-8bggz/vb1nye/nl0e93ri1ouwf9u0/collaborator/join?token=rDXFoa8BMH6VCeD9&source=doc_collaborator#%20%E3%80%8APrometheus%E5%AF%B9%E6%8E%A5%E3%80%8B

http://www.niftyadmin.cn/n/5423775.html

相关文章

Vue3全家桶 - Vue3 - 【3】模板语法(指令+修饰符 + v-model语法糖)

一、模板语法 主要还是记录一些指令的使用和vue2的区别&#xff1b;vue3指令导航&#xff1b; 1.1 v-text 和 v-html 指令的区别&#xff1a; v-text&#xff1a; 更新元素的文本内容&#xff1b;v-text 通过设置元素的 textContent 属性来工作&#xff0c;因此它将覆盖元素…

【嵌入式】嵌入式系统稳定性建设:最后的防线

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟。提供嵌入式方向的学习指导、简历面…

qt如何将QHash中的数据有序地放入到QList中

在qt中&#xff0c;要将QHash中的数据有序地放入到QList中&#xff0c;首先要明白&#xff1a; 我们可以遍历QHash中的键值对&#xff0c;并将其按照键的顺序或值的大小插入到QList中&#xff0c;直接用for循环即可。 #include <QCoreApplication> #include <QHas…

深入理解Nginx日志级别

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;广泛用于提供网站和应用服务。它的强大功能之一是灵活的日志记录能力&#xff0c;允许管理员根据需要配置不同的日志级别。正确理解和使用这些日志级别对于监控、调试和保障你的服务稳定运行至关重要。本文旨在深入介绍…

【Datawhale学习笔记】从大模型到AgentScope

从大模型到AgentScope AgentScope是一款全新的Multi-Agent框架&#xff0c;专为应用开发者打造&#xff0c;旨在提供高易用、高可靠的编程体验&#xff01; 高易用&#xff1a;AgentScope支持纯Python编程&#xff0c;提供多种语法工具实现灵活的应用流程编排&#xff0c;内置…

20240309web前端_第一周作业_完成用户注册界面

作业一&#xff1a;完成用户注册界面 成果展示&#xff1a; 完整代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-…

AIGC——DreamTuner通过单张图片生成与该图片主题风格一致的新图像

简介 DreamTuner的能力在于从单个图像生成主体驱动的新通用方法&#xff0c;这意味着用户只需提供一张图片&#xff0c;DreamTuner就能帮助他们生成与原始图片在主题和风格上一致的新图像。 算法重要之处在于其通用性和个性化定制的能力。无论是需要根据特定主题或条件创建个…

DDR3 NATIVE接口

参考&#xff1a; DDR3 控制器 MIG IP 详解完整版 &#xff08;native&Vivado&Verilog&#xff09;_mig ip核-CSDN博客 APP和AXI接口有许多相似的地方&#xff08;握手部分&#xff09;&#xff0c; 但是由于和物理芯片直接相关&#xff0c;有更多不一样的地方。 a…