# perf **Repository Path**: rippleos/perf ## Basic Information - **Project Name**: perf - **Description**: MOSS 性能监控模块 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-11 - **Last Updated**: 2026-05-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mperf - 性能监控模块 ## 概述 mperf 是 MOSS 中间件的性能监控模块,提供 Prometheus 格式的指标导出,支持运行时可观测性。 ## 设计目标 mperf 的核心目标是:**为 MOSS 中间件提供低开销、标准化的运行时可观测性**。 ``` ┌─────────────────────────────────────────────────────────────┐ │ 设计目标 │ ├─────────────────────────────────────────────────────────────┤ │ 1. 低开销 - 指标采集不影响实时通信性能 (~12ns/op) │ │ 2. 标准化 - Prometheus 格式,生态兼容 │ │ 3. 分层设计 - Topic/Node/System 三层指标 │ │ 4. 零侵入 - 可选集成,不强制依赖 │ └─────────────────────────────────────────────────────────────┘ ``` ## 架构设计 ### 架构分层 ``` ┌─────────────────────────────────────────────────────────────┐ │ Application Layer │ │ (用户代码调用 mperf API) │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Collectors │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │TopicCollector│ │NodeCollector │ │SystemCollector│ │ │ │ 业务指标 │ │ 生命周期 │ │ 资源监控 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ MetricsRegistry │ │ 统一指标管理,封装 prometheus-cpp │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ PrometheusExporter │ │ HTTP /metrics 端点,文本格式导出 │ └─────────────────────────────────────────────────────────────┘ ``` ### 模块定位 ``` ┌─────────────────────────────────────────────────────────────┐ │ Application Layer │ │ (mexem, mvisual, mrecord, mdiag, mupgrade, mparam...) │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ mperf (NEW) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ MetricsReg │ │ SystemMon │ │ Prometheus │ │ │ │ istry │ │ itor │ │ Exporter │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ mcom │ │ msafety │ │ mruntime │ │ (Topic Stats)│ │ (Health) │ │ (Clock) │ └──────────────┘ └──────────────┘ └──────────────┘ ``` ### 依赖关系 ```yaml mperf: depends_on: - mruntime # Clock, 时间工具 - mlog # 日志 optional: - mcom # Topic 统计集成 - msafety # 健康状态导出 external: - prometheus-cpp (v1.3.0+) ``` ### 目录结构 ``` moss/perf/ ├── CMakeLists.txt ├── README.md ├── include/perf/ │ ├── mperf.h # 模块入口 │ ├── types.h # 类型定义 │ ├── metrics_registry.h # 指标注册中心 │ ├── collectors.h # 收集器集合 │ ├── prometheus_exporter.h # Prometheus 导出器 │ └── prometheus_mock.h # Mock 实现(用于编译验证) ├── src/ │ ├── mperf.cpp │ ├── metrics_registry.cpp │ ├── collectors.cpp │ └── prometheus_exporter.cpp ├── test/ │ ├── test_metrics_registry.cpp │ ├── test_collectors.cpp │ ├── test_prometheus_exporter.cpp │ └── test_mperf.cpp └── cmake/ └── mperfConfig.cmake.in ``` ## 核心设计模式 ### 单例 Registry + 多 Collector ```cpp // 设计原理:全局唯一 Registry,多 Collector 共享 class MetricsRegistry { public: static MetricsRegistry& instance(); // 单例 Counter& create_counter(...); // 工厂方法 Gauge& create_gauge(...); Histogram& create_histogram(...); std::string serialize(); // 统一序列化 }; // 每个 Collector 独立管理自己的指标 class TopicCollector { MetricsRegistry& registry_; // 引用共享 Registry std::unordered_map counters_; // 缓存 }; ``` **为什么这样设计?** - Registry 单例:避免多实例导致的指标重复/冲突 - Collector 独立:各模块可独立初始化,解耦 - 缓存指针:避免每次调用都查找,性能优化 ### 指标类型映射 | Prometheus 类型 | 用途 | 性能 | mperf 应用场景 | |-----------------|------|------|----------------| | **Counter** | 单调递增 | ~12ns | 消息计数、字节数 | | **Gauge** | 可增可减 | ~12ns | CPU%、内存、状态 | | **Histogram** | 分布统计 | ~130ns | 延迟、消息大小 | | **Summary** | 分位数 | ~9-19μs | ❌ 不使用(太慢) | **设计决策:** - **热路径只用 Counter/Gauge** - 12ns 开销可忽略 - **Histogram 用于延迟** - 130ns 仍可接受 - **禁用 Summary** - 微秒级开销影响实时性 ### 延迟桶设计 ```cpp // 预定义延迟桶:覆盖 1ms ~ 10s const std::vector LATENCY_BUCKETS_MS = { 1.0, 5.0, 10.0, 25.0, 50.0, // 低延迟区(细粒度) 100.0, 250.0, 500.0, // 中延迟区 1000.0, 2500.0, 5000.0, 10000.0 // 高延迟区(粗粒度) }; ``` **设计原理:** - 低延迟区细分:汽车控制场景延迟通常 < 100ms - 高延迟区粗分:异常情况,不需要精确分位数 - 对数间隔:符合延迟分布特征 ## 数据流 ``` ┌──────────────┐ │ Topic Publish│ │ (用户代码) │ └──────────────┘ │ ▼ record_publish(topic, bytes) ┌──────────────┐ │TopicCollector│ │ 查找/创建 │ │ Counter │ └──────────────┘ │ ▼ increment(bytes) ┌──────────────┐ │ Counter │ │ value += bytes│ ← ~12ns,无锁原子操作 └──────────────┘ │ │ (定期抓取) ▼ ┌──────────────┐ │Prometheus │ │ Scraper │ │GET /metrics │ └──────────────┘ │ ▼ serialize() ┌──────────────┐ │TextSerializer│ │ 格式化为 │ │ Prometheus │ │ 文本格式 │ └──────────────┘ ``` ## 核心组件 ### 1. MetricsRegistry - 指标注册中心 统一的指标管理入口,封装 prometheus-cpp Registry。 ```cpp namespace moss::mperf { class MetricsRegistry { public: static MetricsRegistry& instance(); void init(const std::string& node_name); Counter& create_counter(const std::string& name, const std::string& help, const Labels& labels = {}); Gauge& create_gauge(const std::string& name, const std::string& help, const Labels& labels = {}); Histogram& create_histogram(const std::string& name, const std::string& help, const std::vector& buckets, const Labels& labels = {}); std::string serialize(); std::shared_ptr raw_registry(); }; using Labels = std::map; } // namespace moss::mperf ``` ### 2. TopicCollector - Topic 指标收集器 提供 Topic 级别的指标收集。 ```cpp namespace moss::mperf { class TopicCollector { public: explicit TopicCollector(MetricsRegistry& registry); void record_publish(const std::string& topic, size_t bytes); void record_subscribe(const std::string& topic, size_t bytes); void record_latency(const std::string& topic, double latency_ms); void update_snapshot(const std::string& topic, const TopicStatsSnapshot& snapshot); private: static const std::vector LATENCY_BUCKETS_MS; MetricsRegistry& registry_; std::unordered_map pub_counters_; std::unordered_map sub_counters_; std::unordered_map latency_histograms_; }; } // namespace moss::mperf ``` **导出指标:** | 指标名 | 类型 | 标签 | 说明 | |--------|------|------|------| | `moss_topic_published_bytes_total` | Counter | node, topic | 发布总字节数 | | `moss_topic_subscribed_bytes_total` | Counter | node, topic | 订阅总字节数 | | `moss_topic_message_count_total` | Counter | node, topic, direction | 消息计数 | | `moss_topic_latency_seconds` | Histogram | node, topic | 端到端延迟 | ### 3. SystemCollector - 系统资源收集器 采集 CPU、内存、磁盘等系统级指标。 ```cpp namespace moss::mperf { class SystemCollector { public: explicit SystemCollector(MetricsRegistry& registry); void start(std::chrono::milliseconds interval = std::chrono::seconds(5)); void stop(); void update(); private: void collect_cpu(); void collect_memory(); void collect_disk(); MetricsRegistry& registry_; std::thread collect_thread_; std::atomic running_{false}; }; } // namespace moss::mperf ``` **导出指标:** | 指标名 | 类型 | 标签 | 说明 | |--------|------|------|------| | `moss_process_cpu_percent` | Gauge | node | 进程 CPU 使用率 | | `moss_process_memory_bytes` | Gauge | node | 进程内存使用 | | `moss_system_memory_total_bytes` | Gauge | node | 系统总内存 | | `moss_system_disk_used_bytes` | Gauge | node, mount | 磁盘已用空间 | ### 4. NodeCollector - 节点生命周期指标 记录节点生命周期和服务调用指标。 ```cpp namespace moss::mperf { class NodeCollector { public: explicit NodeCollector(MetricsRegistry& registry); void record_event(NodeEvent event, const std::string& detail = ""); void update_health_status(uint8_t status); void record_service_call(const std::string& service, bool success, double duration_ms); }; enum class NodeEvent { INIT_START, INIT_END, START, STOP, DESTROY, ERROR }; } // namespace moss::mperf ``` **导出指标:** | 指标名 | 类型 | 标签 | 说明 | |--------|------|------|------| | `moss_node_state` | Gauge | node | 节点状态 | | `moss_node_error_total` | Counter | node, type | 错误计数 | | `moss_node_health_status` | Gauge | node | 健康状态 | | `moss_service_latency_seconds` | Histogram | node, service | 服务调用延迟 | ### 5. PrometheusExporter - Prometheus 导出器 提供 HTTP `/metrics` 端点。 ```cpp namespace moss::mperf { class PrometheusExporter { public: struct Config { std::string host{"0.0.0.0"}; uint16_t port{9090}; std::string path{"/metrics"}; bool enabled{true}; }; explicit PrometheusExporter(MetricsRegistry& registry, const Config& config = {}); bool start(); void stop(); uint16_t port() const; std::string scrape(); }; } // namespace moss::mperf ``` ## 性能优化策略 ### 预创建指标 ```cpp // ❌ 错误:每次调用都创建 void record_publish(const std::string& topic, size_t bytes) { auto& counter = registry.create_counter(topic, ...); // 开销大 counter.increment(bytes); } // ✅ 正确:首次创建,后续缓存 void record_publish(const std::string& topic, size_t bytes) { auto it = counters_.find(topic); if (it == counters_.end()) { auto& counter = registry.create_counter(topic, ...); counters_[topic] = &counter; // 缓存 it = counters_.find(topic); } it->second->increment(bytes); // ~12ns } ``` ### 标签基数控制 ```cpp // ❌ 错误:无界标签(内存爆炸) counter.Add({{"request_id", random_uuid()}}); // ✅ 正确:有界标签 counter.Add({{"node", node_name}, {"topic", topic_name}}); // node_name: 有限节点数 // topic_name: 有限 Topic 数 ``` ### 线程安全 prometheus-cpp 内置线程安全: ```cpp class Counter { void Increment(double value) { std::lock_guard lock(mutex_); // 内部锁 value_ += value; } }; ``` ## 与 mcom 集成 ### NodeBaseMoss 集成示例 ```cpp class NodeBaseMoss { // 每个节点实例化自己的 Collector moss::mperf::TopicCollector topic_collector_; moss::mperf::NodeCollector node_collector_; // 发布时自动记录 template void publish_with_metrics(publisher, topic, msg) { publisher->publish(msg); topic_collector_.record_publish(topic, msg.ByteSizeLong()); } }; ``` **设计原则:** - **非侵入式**:通过 `publish_with_metrics` 封装,不修改 mcom - **可选启用**:`metrics_enabled_` 开关控制 - **独立实例**:每个节点独立 Collector,避免竞争 ## 系统指标采集 ```cpp class SystemCollector { void collect_cpu() { // 读取 /proc/stat 和 /proc/self/stat // 计算 CPU 使用率 } void collect_memory() { // 读取 /proc/meminfo 和 /proc/self/statm // 计算内存使用 } void collect_loop(interval) { while (running_) { update(); // 采集 sleep(interval); // 默认 5s } } }; ``` **设计决策:** - **后台线程**:不阻塞主线程 - **低频采集**:5s 间隔,系统指标变化慢 - **Linux 专用**:读取 `/proc`,嵌入式场景可适配 ## 导出格式示例 ``` # HELP moss_topic_published_bytes_total Total bytes published per topic # TYPE moss_topic_published_bytes_total counter moss_topic_published_bytes_total{node="control_node",topic="/control/cmd"} 1234567 # HELP moss_topic_latency_seconds Topic end-to-end latency # TYPE moss_topic_latency_seconds histogram moss_topic_latency_seconds_bucket{node="control_node",topic="/control/cmd",le="0.001"} 100 moss_topic_latency_seconds_bucket{node="control_node",topic="/control/cmd",le="0.005"} 250 moss_topic_latency_seconds_bucket{node="control_node",topic="/control/cmd",le="+Inf"} 500 moss_topic_latency_seconds_sum{node="control_node",topic="/control/cmd"} 12.5 moss_topic_latency_seconds_count{node="control_node",topic="/control/cmd"} 500 # HELP moss_process_cpu_percent Process CPU usage percentage # TYPE moss_process_cpu_percent gauge moss_process_cpu_percent{node="control_node"} 15.5 ``` ## 设计权衡总结 | 决策点 | 选择 | 理由 | |--------|------|------| | 指标库 | prometheus-cpp | 标准实现,C++ 支持,生态兼容 | | Registry | 单例 | 避免冲突,统一导出 | | Collector | 多实例 | 模块解耦,独立初始化 | | 热路径指标 | Counter/Gauge | 12ns 开销可忽略 | | 延迟统计 | Histogram | 130ns 可接受,Summary 太慢 | | 标签设计 | node + topic | 有界基数,内存可控 | | 系统采集 | 后台线程 | 不阻塞实时通信 | | 导出格式 | Prometheus Text | 标准格式,工具链兼容 | ## 使用示例 ```cpp #include "perf/mperf.h" // 初始化 moss::mperf::Config config; config.node_name = "my_node"; config.enable_system_collector = true; config.exporter_config.port = 9090; moss::mperf::Mperf mperf(config); mperf.init(); mperf.start(); // 记录指标 mperf.topic_collector().record_publish("/topic", 1024); mperf.topic_collector().record_latency("/topic", 5.5); mperf.node_collector().record_event(moss::mperf::NodeEvent::START); // 访问 http://localhost:9090/metrics 获取 Prometheus 格式指标 ``` ## CMake 配置 ```cmake cmake_minimum_required(VERSION 3.14) project(mperf VERSION 0.1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) find_package(Threads REQUIRED) # 选项 1: 使用真实 prometheus-cpp find_package(prometheus-cpp REQUIRED) # 选项 2: 使用 Mock(编译验证) option(MPERF_USE_MOCK_PROMETHEUS "Use mock prometheus" OFF) add_library(mperf SHARED src/mperf.cpp src/metrics_registry.cpp src/collectors.cpp src/prometheus_exporter.cpp ) target_link_libraries(mperf PUBLIC prometheus-cpp::core prometheus-cpp::pull Threads::Threads ) ``` ## 测试覆盖 | 测试文件 | 覆盖范围 | |----------|----------| | test_metrics_registry.cpp | Registry 创建、指标注册、序列化 | | test_collectors.cpp | Topic/Node/System Collector | | test_prometheus_exporter.cpp | HTTP 端点、文本格式 | | test_mperf.cpp | 完整模块集成 | **测试结果: 20/20 通过** ## 扩展点 ``` 未来可扩展: ├── 自定义 Collector(用户指标) ├── Push Gateway(主动推送) ├── OpenTelemetry 兼容 ├── 标签动态过滤 └── 指标聚合(多节点汇总) ```