节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
61.59 KiB
Stardust
# 星尘监控系统架构文档 ## 1. 概述 星尘(Stardust)是一个轻量级分布式监控平台,为企业提供应用性能监控(APM)能力。系统采用**客户端采样统计 + 服务端多级汇总**的架构,在保证监控精度的同时,大幅降低了网络传输和存储成本。 ### 1.1 核心设计理念 与传统 APM 系统(如 SkyWalking、Jaeger)全量采集不同,星尘采用: | 特性 | 传统 APM | 星尘 | |------|---------|------| | 数据采集 | 全量采集,服务端聚合 | 客户端采样+统计,服务端汇总 | | 网络开销 | 高(每次调用上报) | 低(周期性批量上报统计) | | 存储压力 | 极高 | 可控 | | 实时性 | 高 | 分钟级 | **核心优势**: - **低成本**:客户端本地统计,减少90%+网络传输和存储 - **可扩展**:支持10亿+日调用量,单机即可处理 - **易部署**:企业内部部署,数据安全可控 - **灵活配置**:支持热更新,无需重启服务 ### 1.2 系统定位 - **目标用户**:企业内部部署 - **典型规模**: - 应用数量:20~100 个 - 埋点总数(TraceItem):几十万个(建议控制在 10 万以内) - 单应用埋点数:100~300 个(不建议超过 1000 个) - 每日跟踪数据(TraceData):2000~5000 万行 - 每日埋点统计调用:10 亿+ 次 ### 1.3 文档结构 本文档包含以下内容: - **第2-4章**:系统架构与核心组件说明 - **第5章**:数据存储与数据库优化 - **第6章**:性能分析与瓶颈识别 - **第7章**:性能优化方案与实施 - **第8章**:配置与调优指南(**重点**) - **第9-10章**:附录与后续计划 --- ## 2. 系统架构 ### 2.1 整体架构图 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 应用层(客户端) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ App A │ │ App B │ │ App C │ │ App ... │ │ │ │ (2实例) │ │ (3实例) │ │ (2实例) │ │ │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ │ │ ┌──────────┴────────────────┴────────────────┘ │ │ │ │ StarTracer(每实例一个) │ │ │ │ - 自动埋点:DB/Redis/HTTP/WebAPI │ │ │ │ - 周期采样(默认60秒) │ │ │ │ - 本地统计:次数/耗时/错误 │ │ └─────┴──→ ProcessSpans() 上报 │ │ │ └───────────────────────────────────┬─────────────────────────────────────────┘ │ HTTP POST (JSON/GZip) │ 每应用每分钟上报一次 │ 每次约50~60个 SpanBuilder ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 服务端(Stardust.Server) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ TraceController │ │ │ │ ┌───────────────┐ ┌───────────────┐ │ │ │ │ │ Report() │ │ ReportRaw() │ ← 压缩数据 │ │ │ │ │ 普通埋点数据 │ │ 大数据量 │ │ │ │ │ └───────┬───────┘ └───────┬───────┘ │ │ │ │ └────────────────────┴──────────────┐ │ │ │ │ ▼ │ │ │ │ ┌───────────────────────────┐ │ │ │ │ │ ProcessData() │ │ │ │ │ │ 1. 过滤异常埋点 │ │ │ │ │ │ 2. GetOrAddItem (?性能) │ │ │ │ │ │ 3. 生成 TraceData │ │ │ │ │ │ 4. 生成 SampleData │ │ │ │ │ │ 5. 批量插入数据库 │ │ │ │ │ └─────────────┬─────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────┼─────────────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌─────────────────────────┐ ┌─────────────────────────┐ ┌────────────┐ │ │ │ TraceStatService │ │ AppDayStatService │ │ ItemStat │ │ │ │ 追踪统计服务 │ │ 应用天统计服务 │ │ 埋点统计 │ │ │ │ (80%资源占用) │ │ │ │ │ │ │ └─────────────────────────┘ └─────────────────────────┘ └────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 2.2 数据流向 ``` 客户端采样周期(60秒) │ ▼ SpanBuilder[] ────────────? TraceController.Report() (50~60个/次) │ ▼ ┌──────────────┐ │ ProcessData │ └──────┬───────┘ │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ TraceData SampleData 统计队列 (跟踪数据) (采样数据) (内存) 31张分表 31张分表 │ │ │ └─────────────────────┘ │ │ │ 批量INSERT数据库 │ │ │ └──────────────? TraceStatService │ ┌─────────────────────────┼─────────────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 分钟统计 │ │ 小时统计 │ │ 天统计 │ │ (5分钟粒度) │ ──────? │ │ ──────? │ │ │TraceMinuteStat│ │TraceHourStat │ │TraceDayStat │ └──────────────┘ └──────────────┘ └──────────────┘ │ ▼ ┌──────────────┐ │ 应用分钟统计 │ │AppMinuteStat │ ──────────────────────────────────? AppDayStat │ (告警数据源) │ (应用天统计) └──────────────┘ ``` --- ## 3. 客户端架构 ### 3.1 StarTracer 核心组件 `StarTracer` 是星尘监控客户端的核心实现,继承自 `DefaultTracer`,位于 `Stardust\Monitors\StarTracer.cs`。 #### 3.1.1 核心职责 | 职责 | 说明 | |------|------| | 自动埋点 | 通过 DI 注入后,自动为 DB/Redis/HTTP/WebAPI 等建立埋点 | | 本地统计 | 在采样周期内收集调用次数、耗时、错误等统计信息 | | 数据上报 | 通过 `ProcessSpans()` 将统计数据上传到星尘服务端 | | 参数同步 | 接收服务端下发的采样参数(周期、采样数等) | #### 3.1.2 关键配置参数 | 参数 | 默认值 | 说明 | |------|--------|------| | `Period` | 60秒 | 采样周期,每周期上报一次 | | `MaxSamples` | 1 | 每周期正常采样数 | | `MaxErrors` | 10 | 每周期异常采样数 | | `MaxFails` | 2880 | 最大失败队列长度(约2天) | | `TrimSelf` | true | 剔除埋点上报自身的调用 | | `EnableMeter` | true | 是否收集应用性能信息 | #### 3.1.3 数据上报流程 ```csharp // StarTracer.ProcessSpans() 核心逻辑 protected override void ProcessSpans(ISpanBuilder[] builders) { // 1. 剔除排除项(Excludes配置 + 上报自身) builders = builders.Where(e => !Excludes.Any(y => y.IsMatch(e.Name))).ToArray(); builders = builders.Where(e => !e.Name.EndsWithIgnoreCase("/Trace/Report")).ToArray(); // 2. 构建上报模型 var model = new TraceModel { AppId = AppId, ClientId = ClientId, // IP@ProcessId Builders = builders, // 50~60个 SpanBuilder Info = _appInfo // 应用性能信息(可选) }; // 3. 根据数据大小选择上报方式 var body = model.ToJson(); var rs = body.Length > 1024 ? client.Invoke<TraceResponse>("Trace/ReportRaw", body.GetBytes()) : // GZip压缩 client.Invoke<TraceResponse>("Trace/Report", model); // 普通JSON // 4. 同步服务端参数 if (rs != null) { Period = rs.Period; MaxSamples = rs.MaxSamples; // ... } } ``` #### 3.1.4 上报数据结构 每个 `SpanBuilder` 包含该埋点在本周期内的统计信息: ```json { "Name": "/api/user/info", // 埋点名称 "StartTime": 1234567890000, // 周期开始时间(Unix毫秒) "EndTime": 1234567950000, // 周期结束时间 "Total": 1000, // 本周期调用总次数 "Errors": 5, // 错误次数 "TotalCost": 15000, // 总耗时(毫秒) "MaxCost": 200, // 最大耗时 "MinCost": 5, // 最小耗时 "Samples": [...], // 正常采样(默认1条) "ErrorSamples": [...] // 异常采样(默认10条) } ``` **关键理解**:客户端在本地已完成统计汇总,一个埋点在一个周期内无论调用 1000 次还是 10000 次,都只上报一条 SpanBuilder。 --- ## 4. 服务端架构 ### 4.1 TraceController 数据接收 位于 `Stardust.Server\Controllers\TraceController.cs`,负责接收和处理客户端上报的埋点数据。 #### 4.1.1 接口定义 | 接口 | 方法 | 说明 | |------|------|------| | `/Trace/Report` | POST | 接收普通埋点数据(JSON) | | `/Trace/ReportRaw` | POST | 接收压缩后的大数据量(GZip) | #### 4.1.2 ProcessData 核心处理流程 ```csharp private void ProcessData(AppTracer app, TraceModel model, Int32 nodeId, String ip, ISpanBuilder[] builders) { var traces = new List<TraceData>(); var samples = new List<SampleData>(); foreach (var item in builders) { // ===== 第一阶段:数据过滤 ===== // 1. 跟踪规则黑名单检查 var rule = TraceRule.Match(item.Name); if (rule != null && !rule.IsWhite) continue; // 2. 应用排除项检查 if (excludes.Any(e => e.IsMatch(item.Name))) continue; // 3. 时间范围检查(拒收超期/未来数据) var timestamp = item.StartTime.ToDateTime().ToLocalTime(); if (timestamp < startTime || timestamp > endTime) continue; // 4. 名称长度检查 if (item.Name.Length > TraceData._.Name.Length) continue; // ===== 第二阶段:获取跟踪项 ===== // ?? 性能瓶颈点:GetOrAddItem var ti = cacheProvider.InnerCache.Get<TraceItem>(key); ti ??= app.GetOrAddItem(item.Name, rule?.IsWhite); cacheProvider.InnerCache.Set(key, ti, 600); // 缓存10分钟 if (!ti.Enable) continue; // ===== 第三阶段:生成入库数据 ===== // 生成跟踪数据 var td = TraceData.Create(item); td.AppId = app.ID; td.ItemId = ti.Id; traces.Add(td); // 生成采样数据 samples.AddRange(SampleData.Create(td, item.Samples, true)); samples.AddRange(SampleData.Create(td, item.ErrorSamples, false)); // 超时处理(累加到错误数) if (timeout > 0 && item.Samples != null) td.Errors += item.Samples.Count(e => e.EndTime - e.StartTime > timeout); } // ===== 第四阶段:批量入库 ===== traces.Insert(true); // 支持自动分表 samples.Insert(true); // ===== 第五阶段:加入统计队列 ===== stat.Add(traces); // TraceStatService appStat.Add(now.Date); // AppDayStatService itemStat.Add(app.ID); // TraceItemStatService } ``` #### 4.1.3 GetOrAddItem 性能分析 `GetOrAddItem` 是已知的性能瓶颈点,位于 `应用跟踪器.Biz.cs`: ```csharp public TraceItem GetOrAddItem(String name, Boolean? whiteOnApi = null) { // 1. 先在有效集合中查找(内存) var list = TraceItems; // 缓存的有效跟踪项列表 var ti = list.FirstOrDefault(e => e.Name.EqualIgnoreCase(name)); if (ti != null) return ti; // 2. 再查全量字典(内存) var dic = _full ??= TraceItem.FindAllByApp(ID) .ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); if (dic.TryGetValue(name, out ti)) return ti; // 3. 规则匹配(可能较慢) ti = list.FirstOrDefault(e => !e.Cloned && e.IsMatch(name)); ti ??= dic.Values.FirstOrDefault(e => !e.Cloned && e.IsMatch(name)); if (ti != null) return ti; // 4. 新建跟踪项(数据库操作) ti = new TraceItem { AppId = ID, Name = name, Enable = ... }; ti.Insert(); list.Add(ti); return ti; } ``` **性能问题**: - 全量字典加载在首次访问时触发,可能阻塞 - 规则匹配需要遍历列表 - 新建跟踪项涉及数据库 INSERT - 当前已有10分钟缓存机制缓解 ### 4.2 TraceStatService 统计服务 位于 `Stardust.Server\Services\TraceStatService.cs`,是星尘服务端的**核心性能瓶颈**,占用约 80% 的服务器资源。 #### 4.2.1 统计架构 ``` ┌──────────────────────────────────────┐ │ TraceStatService │ │ │ │ ┌────────────────────────────────┐ │ │ │ 内存队列 (_queue) │ │ TraceData ──────────? │ │ ConcurrentQueue<TraceData> │ │ (批量添加) │ │ 限制: 100,000 条 │ │ │ └────────────────────────────────┘ │ │ │ │ │ ┌───────────┴───────────┐ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 流式计算 │ │ 批量计算 │ │ │ │ 5秒周期 │ │ 30秒周期 │ │ │ │DoFlowStat│ │DoBatchStat│ │ │ └──────────┘ └──────────┘ │ │ │ └──────────────────────────────────────┘ ``` #### 4.2.2 双模式统计策略(已优化) | 模式 | 周期 | 方法 | 说明 | |------|------|------|------| | 流式计算 | **30秒** | `DoFlowStat()` | 增量累加,仅计算分钟级统计 | | 批量计算 | **60秒** | `DoBatchStat()` | 覆盖计算,处理小时/天级统计 | **流式计算(DoFlowStat)**: - 从队列中取出 TraceData - **仅更新分钟级统计**(TraceMinuteStat + AppMinuteStat),用于告警 - 每次最多处理 100,000 条 - 使用延迟队列(EntityDeferredQueue)批量更新数据库 **批量计算(DoBatchStat)**: - 根据时间维度重新计算 - 从下级统计表聚合到上级(小时/天统计) - 用于修正流式计算的偏差 **延迟队列配置(已优化)**: | 队列 | 周期 | 说明 | |------|------|------| | MinuteQueue | 120秒 | 分钟统计,告警数据源,需要较高实时性 | | AppMinuteQueue | 120秒 | 应用分钟统计,同上 | | HourQueue | 180秒 | 小时统计,实时性要求低 | | DayQueue | 180秒 | 天统计,实时性要求低 | #### 4.2.3 多级统计汇总 ``` 原始数据 TraceData │ │ (流式增量 + 批量覆盖) ▼ ┌───────────────────────────────────────────────────────────────────────────┐ │ 分钟级统计 (5分钟粒度) │ │ TraceMinuteStat: 每应用每埋点每5分钟一行 │ │ AppMinuteStat: 每应用每5分钟一行 (用于告警) │ │ 每天数据量: < 200万行 (10万埋点 × 288个5分钟周期,实际远小于此) │ └───────────────────────────────────────────────────────────────────────────┘ │ │ (批量聚合) ▼ ┌───────────────────────────────────────────────────────────────────────────┐ │ 小时级统计 │ │ TraceHourStat: 每应用每埋点每小时一行 │ │ 由 TraceMinuteStat 聚合生成 │ └───────────────────────────────────────────────────────────────────────────┘ │ │ (批量聚合) ▼ ┌───────────────────────────────────────────────────────────────────────────┐ │ 天级统计 │ │ TraceDayStat: 每应用每埋点每天一行 │ │ AppDayStat: 每应用每天一行 (衡量应用压力负载) │ │ 由 TraceHourStat 聚合生成 │ └───────────────────────────────────────────────────────────────────────────┘ ``` #### 4.2.4 统计字段说明 每级统计都包含以下核心指标: | 字段 | 类型 | 说明 | |------|------|------| | `Total` | Int64 | 调用总次数 | | `Errors` | Int64 | 错误次数 | | `TotalCost` | Int64 | 总耗时(毫秒) | | `MaxCost` | Int32 | 最大耗时 | | `MinCost` | Int32 | 最小耗时 | | `Cost` | Int32 | 平均耗时(TP99近似) | | `TotalValue` | Int64 | 用户数值累计 | | `RingRate` | Double | 环比(与昨日同期对比) | **TP99 计算逻辑**: ```csharp // 当调用次数 >= 50 时,去掉头部1%的最大值后计算平均 if (st.Total >= 50) { var totalCost = st.TotalCost; var ms = vs.Select(e => e.MaxCost).OrderByDescending(e => e).ToList(); var n = (Int32)Math.Round(st.Total * 0.01); for (var i = 0; i < n && i < ms.Count; i++) { totalCost -= ms[i]; } st.Cost = (Int32)Math.Round((Double)totalCost / (st.Total - n)); } ``` #### 4.2.5 延迟队列机制 使用 `EntityDeferredQueue` 实现批量数据库更新: ```csharp internal class MyQueue : EntityDeferredQueue { public Int32 Period { get; set; } = 60; // 60秒批量提交 public override Int32 Process(IList<Object> list) { return list.Cast<IEntity>().Update(); // 批量UPDATE } } ``` **队列类型**: - `DayQueue`: 天统计延迟队列 - `HourQueue`: 小时统计延迟队列 - `MinuteQueue`: 分钟统计延迟队列 - `AppMinuteQueue`: 应用分钟统计延迟队列 ### 4.3 AppDayStatService 应用天统计 位于 `Stardust.Server\Services\AppDayStatService.cs`,负责应用维度的天级统计。 #### 4.3.1 处理逻辑 ```csharp private void Process(DateTime date) { // 1. 从 TraceDayStat 按应用分组聚合 var list = TraceDayStat.SearchGroupAppAndType(date); // 2. 计算各类型调用量 foreach (var group in list.GroupBy(e => e.AppId)) { var st = AppDayStat.FindOrCreate(date, group.Key); st.Total = group.Sum(e => e.Total); st.Errors = group.Sum(e => e.Errors); // 分类统计 st.Apis = group.Where(e => e.Type == "api").Sum(e => e.Total); st.Https = group.Where(e => e.Type == "http").Sum(e => e.Total); st.Dbs = group.Where(e => e.Type == "db").Sum(e => e.Total); st.Mqs = group.Where(e => e.Type == "mq").Sum(e => e.Total); st.Redis = group.Where(e => e.Type == "redis").Sum(e => e.Total); // 计算环比 var yesterday = AppDayStat.Find(date.AddDays(-1), group.Key); st.RingRate = yesterday?.Total > 0 ? (Double)st.Total / yesterday.Total : 1; st.Save(); } } ``` --- ## 5. 数据存储 ### 5.1 数据库选型 | 数据库 | 使用场景 | |--------|----------| | MySQL | 生产环境主库 | | SQLite | 小规模部署/测试 | **典型配置**: - 低配:4核8G - 推荐:16核32G ### 5.2 核心数据表 #### 5.2.1 数据表概览 | 表名 | 说明 | 分表策略 | 每日数据量 | |------|------|----------|-----------| | `TraceData` | 跟踪数据(原始) | 31张表(按天) | 2000~5000万行 | | `SampleData` | 采样数据(明细) | 31张表(按天) | 几千万行 | | `TraceMinuteStat` | 分钟统计 | 无 | < 200万行 | | `TraceHourStat` | 小时统计 | 无 | < 20万行 | | `TraceDayStat` | 天统计 | 无 | < 10万行 | | `AppMinuteStat` | 应用分钟统计 | 无 | < 3万行 | | `AppDayStat` | 应用天统计 | 无 | < 100行 | | `TraceItem` | 跟踪项(埋点定义) | 无 | < 10万行 | | `AppTracer` | 应用跟踪器配置 | 无 | < 1000行 | #### 5.2.2 分表策略 `TraceData` 和 `SampleData` 采用按天分表: ```csharp // TraceData.cs static TraceData() { Meta.ShardPolicy = new TimeShardPolicy(nameof(Id), Meta.Factory) { TablePolicy = "{0}_{1:dd}", // 如 TraceData_01, TraceData_02, ... Step = TimeSpan.FromDays(1), }; } ``` **分表优势**: - 31张表循环使用 - 便于数据清理(直接 TRUNCATE 过期表) - 避免单表过大 #### 5.2.3 数据保留策略 | 保留天数 | 适用场景 | |---------|---------| | 3~7天 | 数据库压力大 | | 7~15天 | 标准配置 | | 15~30天 | 高配环境 | ### 5.3 数据库优化 #### 5.3.1 MySQL 压缩表 ```csharp // TraceData 启用压缩表 var table = Meta.Table.DataTable; table.Properties["ROW_FORMAT"] = "COMPRESSED"; table.Properties["KEY_BLOCK_SIZE"] = "4"; ``` #### 5.3.2 XCode 累加字段 统计表使用累加字段减少锁竞争: ```csharp // TraceMinuteStat.cs static TraceMinuteStat() { var df = Meta.Factory.AdditionalFields; df.Add(nameof(Total)); df.Add(nameof(Errors)); df.Add(nameof(TotalCost)); // 生成 SQL: UPDATE ... SET Total=Total+@Total ... } ``` --- ## 6. 性能分析 ### 6.1 实际运行指标 基于生产环境数据收集: | 指标 | 实际值 | 说明 | |------|--------|------| | _queue 队列积压 | < 1000 条 | 远低于10万限制,流式计算压力不大 | | 批量计算修正能力 | 完全修正 | 可以更激进地优化流式计算 | | 告警延迟容忍度 | 3~5 分钟 | 统计频率可大幅降低 | | 统计数据查看率 | < 1% | 99%+ 数据无人查看 | ### 6.2 性能瓶颈点 #### 6.2.1 延迟队列 UPDATE(**主要瓶颈**) **问题**:4个延迟队列频繁批量提交,产生大量 UPDATE 操作 **原因**:统计表的频繁更新导致数据库 CPU 和 IO 都很高 **已优化**: - 延长队列提交周期(60秒 → 120~180秒) - 流式计算仅更新分钟级统计,小时/天级交给批量计算 #### 6.2.2 流式计算频率(已优化) **问题**:原来每5秒执行一次,队列积压却只有1000条 **已优化**:调整为每30秒执行一次,减少 83% 的计算频率 #### 6.2.3 GetOrAddItem(中等) **问题**:每次上报都需要查找/创建跟踪项 **现状**:已有 10 分钟缓存 **优化空间**: - 延长缓存时间 - 预热常用跟踪项 ### 6.3 优化效果预估 | 指标 | 优化前 | 优化后 | 改善 | |------|--------|--------|------| | 流式计算频率 | 每5秒 | 每30秒 | -83% | | 批量计算频率 | 每30秒 | 每60秒 | -50% | | 延迟队列提交 | 每60秒 | 每120~180秒 | -50~67% | | 流式计算维度 | 4个(天/时/分/应用分) | 2个(分/应用分) | -50% | | 预计CPU占用 | 80%+ | 30%- | -60% | | 预计数据库IO | 高 | 低 | -60% | ### 6.4 并发估算 | 指标 | 数值 | 说明 | |------|------|------| | 在线应用 | 100个 | 典型企业规模 | | 应用实例 | 200个 | 平均每应用2实例 | | 上报频率 | 60秒/次 | 默认配置 | | 并发上报 | ~3.3个/秒 | 200/60 | | 每次SpanBuilder | 50~60个 | 平均估计 | | 每秒TraceData | ~200条 | 3.3 × 60 | **结论**:并发压力不大,主要瓶颈在统计服务的数据库 UPDATE 操作。 --- ## 7. 性能优化 ### 7.1 问题诊断 #### 7.1.1 性能瓶颈定位 根据慢 SQL 日志、埋点数据和运维经验,性能瓶颈集中在: | 瓶颈点 | 严重程度 | 原因 | 影响 | |--------|---------|------|------| | 延迟队列 UPDATE | **严重** | 4个延迟队列每60秒批量提交 | 数据库CPU和IO高 | | 流式计算频率 | 中等 | 每5秒执行一次,过于频繁 | CPU占用高 | | GetOrAddItem | 中等 | 埋点查找/创建涉及数据库 | 首次访问慢 | #### 7.1.2 关键数据指标(生产环境) 基于生产环境数据收集: | 指标 | 实际值 | 说明 | 优化意义 | |------|--------|------|----------| | _queue 队列积压 | < 1000 条 | 远低于10万限制 | 流式计算可降频 | | 批量计算修正能力 | 完全修正 | 能修正流式计算偏差 | 可激进优化流式计算 | | 告警延迟容忍度 | 3~5 分钟 | 业务可接受范围 | 统计频率可大幅降低 | | 统计数据查看率 | < 1% | 99%+ 数据无人查看 | 适合按需计算 | | 主要性能瓶颈 | 延迟队列 UPDATE | 占用80%+资源 | 重点优化方向 | ### 7.2 优化策略 #### 7.2.1 核心思路 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 三级优化策略 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. 参数调优(立即见效,风险低) │ │ - 延长延迟队列提交周期:60秒 → 120~180秒 │ │ - 降低流式计算频率:5秒 → 30秒 │ │ - 适度降低批量计算频率:30秒 → 60秒 │ │ │ │ 2. 精简流式计算(中等风险) │ │ - 仅计算分钟级统计(告警数据源) │ │ - 小时/天级统计交给批量计算 │ │ │ │ 3. 按需计算(进阶优化,低风险) │ │ - 用户查看时加速计算 │ │ - 无人关注时降低频率 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` #### 7.2.2 优化效果预估 | 指标 | 优化前 | 优化后 | 改善 | |------|--------|--------|------| | 流式计算频率 | 每5秒 | 每30秒 | -83% | | 批量计算频率 | 每30秒 | 每60秒 | -50% | | 延迟队列提交 | 每60秒 | 每120~180秒 | -50~67% | | 流式计算维度 | 4个(天/时/分/应用分) | 2个(分/应用分) | -50% | | 预计CPU占用 | 80%+ | 30%- | -60% | | 预计数据库IO | 高 | 低 | -60% | | 告警延迟 | 1~2分钟 | 2~3分钟 | 可接受 | ### 7.3 已实施的优化 #### 7.3.1 参数调优(已完成) **默认配置恢复**: ```csharp // TraceStatService.cs - 恢复默认配置 public Int32 FlowPeriod { get; set; } = 5; // 流计算周期:5秒 public Int32 BatchPeriod { get; set; } = 30; // 批计算周期:30秒 public Int32 SavePeriod { get; set; } = 60; // 落盘保存周期:60秒 ``` **说明**:默认配置适合大多数场景,可通过配置文件动态调整(详见第8章)。 **优化配置(生产环境推荐)**: ```csharp // 低配服务器(4核8G)推荐配置 public Int32 FlowPeriod { get; set; } = 30; // 5秒 → 30秒 public Int32 BatchPeriod { get; set; } = 60; // 30秒 → 60秒 // 延迟队列配置 private readonly DayQueue _dayQueue = new() { Period = 180 }; // 60秒 → 180秒 private readonly HourQueue _hourQueue = new() { Period = 180 }; // 60秒 → 180秒 private readonly MinuteQueue _minuteQueue = new() { Period = 120 }; // 60秒 → 120秒(告警相关,稍短) private readonly AppMinuteQueue _appMinuteQueue = new() { Period = 120 }; // 同上 ``` **风险评估**:低。批量计算能完全修正流式计算偏差。 #### 7.3.2 流式计算精简(已完成) **优化前**:流式计算同时更新 4 个统计维度(天/小时/分钟/应用分钟) **优化后**:流式计算只更新分钟级统计,小时/天级交给批量计算 ```csharp /// <summary>流式计算,增量累加</summary> private void DoFlowStat(Object state) { // ... 前置代码 ... // ========== 保留:分钟级统计(告警数据源) ========== // 分钟统计 { var st = _minuteQueue.GetOrAdd(td.StatMinute, td.AppId, td.ItemId, out var key); st.Total += td.Total; st.Errors += td.Errors; // ... 统计逻辑 ... _minuteQueue.Commit(key); } // 应用分钟统计 { var st = _appMinuteQueue.GetOrAdd(td.StatMinute, td.AppId, out var key); st.Total += td.Total; st.Errors += td.Errors; // ... 统计逻辑 ... _appMinuteQueue.Commit(key); } // ========== 移除:小时/天统计(交给批量计算) ========== // 原 _dayQueue 和 _hourQueue 流式更新代码已删除 } ``` **效果**: - CPU占用减少50% - 内存操作减少50% - 告警延迟增加约1分钟(可接受) ### 7.4 后续优化方向 #### 7.4.1 GetOrAddItem 缓存优化 **当前**:10分钟缓存 **优化**:延长缓存时间或批量预热 ```csharp // 方案1:延长缓存时间 cacheProvider.InnerCache.Set(key, ti, 1800); // 10分钟 → 30分钟 // 方案2:应用首次上报时预热所有跟踪项 public void PreloadItems(Int32 appId) { var items = TraceItem.FindAllByApp(appId); foreach (var item in items) { var key = $"trace:Item:{appId}-{item.Name}"; cacheProvider.InnerCache.Set(key, item, 1800); } } ``` **预期效果**:减少数据库查询,提升上报接口响应速度。 #### 7.4.2 按需计算(进阶优化) **核心思路**:99% 的统计数据无人查看,可大幅降低计算频率 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Stardust.Web (管理端) │ ├─────────────────────────────────────────────────────────────────┤ │ 用户访问应用A统计页面 │ │ │ │ │ ▼ │ │ 广播关注事件(每分钟2次) │ │ { AppId: A, FocusExpire: 5分钟 } │ │ │ │ └─────────┼───────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Stardust.Server (服务端) │ ├─────────────────────────────────────────────────────────────────┤ │ TraceStatService │ │ │ │ │ ▼ │ │ ┌────────────────────────────────────────────────┐ │ │ │ 关注列表 │ │ │ │ { AppId: A, ExpireTime: now+5min } │ │ │ └────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────────────────────────────────┐ │ │ │ 统计调度策略 │ │ │ │ - 高优先级应用:每5秒统计 │ │ │ │ - 普通应用:每5分钟统计 │ │ │ │ - 低活跃应用:每15分钟统计 │ │ │ └────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **实现示例**: ```csharp /// <summary>追踪统计服务(优化版)</summary> public class TraceStatService : ITraceStatService { /// <summary>关注的应用列表(正在被查看的应用)</summary> private readonly ConcurrentDictionary<Int32, DateTime> _focusedApps = new(); /// <summary>标记应用为关注状态(有人正在查看)</summary> /// <param name="appId">应用ID</param> /// <param name="duration">关注持续时间,默认5分钟</param> public void Focus(Int32 appId, TimeSpan? duration = null) { var expire = DateTime.Now.Add(duration ?? TimeSpan.FromMinutes(5)); _focusedApps.AddOrUpdate(appId, expire, (k, v) => expire); } /// <summary>判断应用是否被关注</summary> private Boolean IsFocused(Int32 appId) { if (_focusedApps.TryGetValue(appId, out var expire)) { if (expire > DateTime.Now) return true; _focusedApps.TryRemove(appId, out _); } return false; } } ``` **预期效果**: - 用户关注的应用:实时性高(5秒级) - 其他应用:降低频率(5~15分钟) - 整体 CPU 下降 50%+ #### 7.4.3 智能调度 根据当前负载动态调整统计频率: - **高峰期**:降低频率,保护数据库 - **低谷期**:提高频率,加速统计 - **告警触发时**:提高相关应用的计算频率 ### 7.5 回滚方案 如果优化后出现问题,可以: 1. **快速回滚**:通过配置文件将参数改回原值,无需重启 2. **部分回滚**:只回滚延迟队列周期,保留流式计算降频 3. **监控指标**:关注以下指标判断是否需要回滚 | 指标 | 正常范围 | 异常阈值 | 处理方式 | |------|---------|---------|----------| | _queue 积压量 | < 1000 | > 10000 | 降低FlowPeriod | | 告警延迟 | < 3分钟 | > 5分钟 | 降低FlowPeriod | | CPU 使用率 | < 50% | > 80% | 增大各周期参数 | | 数据库 TPS | 正常 | 持续高位 | 增大SavePeriod | --- ## 8. 配置与调优指南 > **本章重点**:如何根据实际情况调整星尘监控的性能参数,是运维人员的必读章节。 ### 8.1 核心周期参数 星尘监控有三个核心周期参数,直接影响性能和实时性: | 参数 | 默认值 | 作用 | 影响范围 | |------|--------|------|----------| | **FlowPeriod** | 5秒 | 流式计算周期 | 告警延迟、CPU占用 | | **BatchPeriod** | 30秒 | 批量计算周期 | 数据修正速度、IO压力 | | **SavePeriod** | 60秒 | 落盘保存周期 | 数据持久化、数据库UPDATE压力(**主要瓶颈**) | #### 8.1.1 FlowPeriod - 流式计算周期 **作用**:处理内存队列中的追踪数据,计算分钟级统计(告警数据源)。 | 调整方向 | 优点 | 缺点 | 适用场景 | |---------|------|------|----------| | **调小(如3秒)** | 实时性更好,告警延迟低 | CPU占用高 | 告警要求极高(1分钟内响应) | | **默认(5秒)** | 平衡实时性与性能 | - | 大多数场景 | | **调大(如30秒)** | CPU占用低 | 告警延迟增加 | 低配服务器,告警容忍3-5分钟 | **队列积压参考**: - 积压 < 1000条:可调大至30秒 - 积压 1000-5000条:保持5秒 - 积压 > 5000条:考虑调小至3秒或扩容 #### 8.1.2 BatchPeriod - 批量计算周期 **作用**:从数据库重新聚合数据,修正流式计算的偏差,计算小时/天级统计。 | 调整方向 | 优点 | 缺点 | 适用场景 | |---------|------|------|----------| | **调小(如15秒)** | 数据修正更及时 | CPU和数据库IO压力增大 | 数据准确性要求高 | | **默认(30秒)** | 平衡修正速度与性能 | - | 大多数场景 | | **调大(如60秒)** | 减少CPU和IO压力 | 数据修正延迟 | 低配服务器,容忍3-5分钟延迟 | **修正能力说明**: - 批量计算能完全修正流式计算的偏差 - 即使FlowPeriod调大至60秒,BatchPeriod仍能在30-60秒内修正数据 - 因此可以放心调大FlowPeriod #### 8.1.3 SavePeriod - 落盘保存周期(**主要性能瓶颈**) **作用**:延迟队列批量提交统计数据到数据库的周期。 | 调整方向 | 优点 | 缺点 | 适用场景 | |---------|------|------|----------| | **调小(如30秒)** | 数据持久化更快,重启时数据丢失少 | 数据库UPDATE压力大(**主要瓶颈**) | 服务频繁重启,数据不能丢失 | | **默认(60秒)** | 平衡持久化与性能 | - | 大多数场景 | | **调大(如120-180秒)** | **大幅减少**数据库UPDATE次数,降低IO压力 | 重启时可能丢失更多内存数据 | 低配服务器,服务稳定 | **性能提升效果**: - SavePeriod从60秒调至180秒:数据库UPDATE减少67%,CPU和IO明显下降 - **这是性能优化的重点参数**,调大效果最明显 **数据丢失风险评估**: - SavePeriod=60秒:重启时最多丢失1分钟数据 - SavePeriod=180秒:重启时最多丢失3分钟数据 - 对于监控数据,3分钟的数据丢失是可接受的 ### 8.2 配置方法 #### 8.2.1 通过配置文件修改(推荐) 在 `appsettings.json` 或数据库配置中添加: ```json { "StarServer": { "MonitorFlowPeriod": 5, // 流计算周期(秒) "MonitorBatchPeriod": 30, // 批计算周期(秒) "MonitorSavePeriod": 60 // 落盘保存周期(秒) } } ``` **优势**: - 支持热更新,无需重启服务 - 配置变更会自动同步到服务 **生效机制**: ```csharp // Startup.cs - 配置变更时自动更新服务参数 StarServerSetting.Provider.Changed += (s, e) => { traceService.FlowPeriod = set.MonitorFlowPeriod; traceService.BatchPeriod = set.MonitorBatchPeriod; traceService.SavePeriod = set.MonitorSavePeriod; appStatService.BatchPeriod = set.MonitorBatchPeriod; }; ``` #### 8.2.2 通过管理界面修改 在星尘管理后台 → **系统配置** → **StarServer** → **监控配置**中可以动态修改这些参数。 **操作步骤**: 1. 登录星尘管理后台 2. 进入"配置中心"→"StarServer"配置 3. 找到监控相关配置项 4. 修改并保存 5. 配置立即生效,**无需重启服务** ### 8.3 典型场景配置 #### 8.3.1 场景1:低配服务器(4核8G) **问题**:CPU占用高(80%+),数据库IO压力大 **推荐配置**:保守配置,降低数据库压力 ```json { "MonitorFlowPeriod": 30, // 5秒 → 30秒(降低CPU) "MonitorBatchPeriod": 60, // 30秒 → 60秒(降低IO) "MonitorSavePeriod": 180 // 60秒 → 180秒(大幅降低数据库UPDATE压力) } ``` **预期效果**: - CPU占用:从80%降至30% - 数据库IO:降低60%+ - 告警延迟:2~3分钟(可接受) - 数据丢失风险:重启时最多丢失3分钟数据 **适用条件**: - 服务稳定,很少重启 - 告警可容忍3-5分钟延迟 - 数据库压力大 #### 8.3.2 场景2:高配服务器(16核32G+) **目标**:保持实时性,充分利用资源 **推荐配置**:保持默认或提高实时性 ```json { "MonitorFlowPeriod": 5, // 保持5秒(实时性) "MonitorBatchPeriod": 30, // 保持30秒 "MonitorSavePeriod": 60 // 保持60秒 } ``` **适用条件**: - 服务器资源充足 - 对告警实时性要求高 - 数据库性能好 #### 8.3.3 场景3:告警要求极高 **需求**:告警必须在1分钟内响应 **推荐配置**:提高实时性 ```json { "MonitorFlowPeriod": 5, // 保持5秒或调小至3秒 "MonitorBatchPeriod": 30, // 保持30秒 "MonitorSavePeriod": 30 // 60秒 → 30秒(提高实时性,但增加数据库压力) } ``` **权衡**: - 告警延迟:1分钟内 - 代价:数据库UPDATE压力增大一倍 - 建议:优化数据库(如使用SSD、增加内存) #### 8.3.4 场景4:数据库压力大 **问题**:数据库CPU和IO持续高位,慢SQL频繁 **推荐配置**:大幅降低数据库压力 ```json { "MonitorFlowPeriod": 30, // 降低CPU "MonitorBatchPeriod": 60, // 降低IO "MonitorSavePeriod": 180 // **重点**:大幅降低UPDATE压力 } ``` **进一步优化**: - 启用MySQL压缩表(已实现) - 使用XCode累加字段(已实现) - 考虑数据库扩容或使用SSD #### 8.3.5 场景5:混合环境 **场景**:有些应用告警要求高,有些要求低 **推荐方案**:使用按需计算(第7.4.2节) ```csharp // 用户查看应用A统计页面时,加速该应用的计算 _statService.Focus(appId, TimeSpan.FromMinutes(5)); ``` **效果**: - 关注的应用:5秒级实时性 - 其他应用:5-15分钟计算一次 - 整体CPU下降50%+ ### 8.4 参数调优流程 #### 8.4.1 调优步骤 1. **观察现状**: - CPU使用率 - 数据库TPS和慢SQL - 队列积压情况(_queue.Count) - 告警延迟 2. **识别瓶颈**: - CPU高 → 降低FlowPeriod和BatchPeriod - 数据库IO高 → 增大SavePeriod(**优先**) - 告警延迟大 → 降低FlowPeriod - 队列积压多 → 降低FlowPeriod或扩容 3. **调整参数**: - 一次只调整一个参数 - 调整幅度:20%-50%(如5秒→10秒或5秒→30秒) - 通过配置文件修改,无需重启 4. **观察效果**: - 观察1-2小时,确认指标改善 - 关注告警延迟是否在可接受范围 - 确认队列积压没有持续增长 5. **继续优化或回滚**: - 效果好 → 考虑进一步优化 - 告警延迟过大 → 回滚或降低调整幅度 #### 8.4.2 快速调优建议 **第一步**:增大SavePeriod(效果最明显) ```json { "MonitorSavePeriod": 120 // 60秒 → 120秒 } ``` 观察1小时,如果数据库压力明显下降且告警延迟可接受,继续第二步。 **第二步**:增大FlowPeriod和BatchPeriod ```json { "MonitorFlowPeriod": 10, // 5秒 → 10秒 "MonitorBatchPeriod": 60, // 30秒 → 60秒 "MonitorSavePeriod": 180 // 120秒 → 180秒 } ``` 观察1-2小时,如果效果好,可以进一步调大FlowPeriod至30秒。 ### 8.5 监控指标 #### 8.5.1 关键指标 调整配置后,建议关注以下指标: | 指标 | 正常范围 | 异常阈值 | 处理方式 | |------|---------|---------|----------| | **_queue 队列积压** | < 1000 | > 10000 | 降低FlowPeriod或扩容 | | **CPU 使用率** | < 50% | > 80% | 增大各周期参数 | | **数据库 TPS** | 正常 | 持续高位 | 增大SavePeriod | | **告警延迟** | < 3分钟 | > 5分钟 | 降低FlowPeriod | | **慢SQL数量** | 0 | > 10/分钟 | 增大SavePeriod,优化数据库 | | **内存使用** | 正常 | 持续增长 | 检查队列积压,可能需要扩容 | #### 8.5.2 监控方式 **方式1:星尘管理后台** - 查看应用监控数据 - 查看服务器性能指标 - 查看告警延迟统计 **方式2:数据库监控** ```sql -- 查看慢SQL SHOW FULL PROCESSLIST; -- 查看TPS SHOW GLOBAL STATUS LIKE 'Questions'; SHOW GLOBAL STATUS LIKE 'Uptime'; -- TPS = (Questions2 - Questions1) / (Uptime2 - Uptime1) ``` **方式3:应用日志** ```csharp // TraceStatService 会输出队列长度 using var span = _tracer?.NewSpan("TraceFlowStat", new { queue = _count }); ``` ### 8.6 常见问题与解决 #### 8.6.1 问题:告警延迟过大(> 5分钟) **原因**: - FlowPeriod设置过大 - 队列积压严重 - 批量计算太慢 **解决**: 1. 降低FlowPeriod(如30秒→10秒) 2. 检查队列积压情况 3. 降低BatchPeriod(如60秒→30秒) #### 8.6.2 问题:CPU占用过高(> 80%) **原因**: - FlowPeriod和BatchPeriod设置过小 - 应用数量或埋点数过多 - 服务器配置过低 **解决**: 1. 增大FlowPeriod(如5秒→30秒) 2. 增大BatchPeriod(如30秒→60秒) 3. 增大SavePeriod(如60秒→180秒) 4. 考虑服务器扩容 #### 8.6.3 问题:数据库IO持续高位 **原因**: - SavePeriod设置过小 - 统计数据量过大 - 数据库配置不足 **解决**: 1. **优先**:增大SavePeriod(如60秒→180秒) 2. 启用MySQL压缩表(已实现) 3. 调整数据保留策略(如7天→3天) 4. 考虑数据库扩容或使用SSD #### 8.6.4 问题:队列积压持续增长 **原因**: - FlowPeriod设置过大,处理速度跟不上 - 突发流量导致数据量激增 - 服务器资源不足 **解决**: 1. 立即降低FlowPeriod(如30秒→5秒) 2. 检查是否有异常流量 3. 临时扩容或限流 #### 8.6.5 问题:重启后丢失数据 **原因**: - SavePeriod设置过大 - 服务异常退出,未及时落盘 **解决**: 1. 降低SavePeriod(如180秒→60秒) 2. 确保服务正常关闭(优雅退出) 3. 监控数据量的重要性平衡 ### 8.7 配置最佳实践 #### 8.7.1 推荐配置矩阵 | 服务器配置 | FlowPeriod | BatchPeriod | SavePeriod | 说明 | |-----------|-----------|-------------|-----------|------| | 2核4G | 60秒 | 120秒 | 300秒 | 极低配,仅演示 | | 4核8G | 30秒 | 60秒 | 180秒 | 低配生产环境 | | 8核16G(推荐) | 10秒 | 30秒 | 120秒 | 标准生产环境 | | 16核32G+ | 5秒 | 30秒 | 60秒 | 高配,注重实时性 | #### 8.7.2 调优原则 1. **优先调整SavePeriod**:这是性能瓶颈,效果最明显 2. **逐步调整**:一次只调一个参数,观察效果 3. **业务优先**:告警延迟不能超过业务容忍度 4. **监控先行**:调整前后都要监控关键指标 5. **留有余量**:不要把参数调到极限,留20%余量 #### 8.7.3 不推荐的配置 | 配置 | 问题 | 说明 | |------|------|------| | FlowPeriod < 3秒 | CPU占用过高 | 队列积压<1000时没必要 | | FlowPeriod > 60秒 | 告警延迟过大 | 超过1分钟告警意义不大 | | SavePeriod < 30秒 | 数据库压力大 | 除非服务频繁重启 | | SavePeriod > 300秒 | 数据丢失风险大 | 重启时丢失5分钟数据 | | 所有周期都很小 | 资源浪费 | 没必要过度实时 | | 所有周期都很大 | 告警无意义 | 监控失去实时性 | ### 8.8 配置变更记录 建议记录每次配置变更,便于问题追溯: | 日期 | 变更内容 | 原因 | 效果 | 操作人 | |------|---------|------|------|--------| | 2026-02-03 | SavePeriod: 60→180秒 | 数据库IO高 | CPU降至30%,IO降低60% | 运维 | | 2026-02-05 | FlowPeriod: 5→30秒 | CPU占用高 | CPU进一步降至20% | 运维 | | ... | ... | ... | ... | ... | --- ## 9. 附录 ### 9.1 已确认信息(生产环境数据) 根据生产环境数据和运维经验,以下问题已确认: | 问题 | 确认结果 | 影响 | 优化建议 | |------|---------|------|----------| | 队列积压情况 | < 1000 条,极少达到10万 | 流式计算压力不大 | FlowPeriod可调大至30秒 | | 批量计算准确性 | 能完全修正流式计算偏差 | 可激进优化流式计算 | 放心调大FlowPeriod | | 告警延迟容忍度 | 3~5 分钟 | 统计频率可大幅降低 | BatchPeriod可调大至60秒 | | 统计数据查看率 | 99%+ 无人查看 | 适合按需计算 | 实施按需计算方案 | | 主要性能瓶颈 | 延迟队列 UPDATE 操作 | 占用80%+资源 | **优先增大SavePeriod** | ### 9.2 关键代码位置 | 功能 | 文件路径 | 说明 | |------|---------|------| | 客户端核心 | `Stardust\Monitors\StarTracer.cs` | 数据采集与上报 | | 服务端接收 | `Stardust.Server\Controllers\TraceController.cs` | 数据接收与处理 | | 追踪统计服务 | `Stardust.Server\Services\TraceStatService.cs` | 流式/批量计算 | | 应用天统计服务 | `Stardust.Server\Services\AppDayStatService.cs` | 应用级统计 | | 应用跟踪器 | `Stardust.Data\Monitors\应用跟踪器.Biz.cs` | GetOrAddItem逻辑 | | 跟踪数据实体 | `Stardust.Data\Monitors\跟踪数据.Biz.cs` | 数据模型 | | 分钟统计实体 | `Stardust.Data\Monitors\跟踪分钟统计.Biz.cs` | 统计模型 | | 配置管理 | `Stardust.Server\Setting.cs` | 周期参数配置 | | 启动配置 | `Stardust.Server\Startup.cs` | 服务注入与配置 | ### 9.3 相关文档 | 文档 | 说明 | |------|------| | [链路追踪 ITracer 接口规范](/NewLife/Stardust/Blob/master/Doc/../NewLife.Core/Doc/链路追踪ITracer.md) | Tracer接口设计 | | [星尘分布式服务平台](https://newlifex.com/blood/stardust) | 官方文档 | | 本文档第8章 | **配置与调优指南(重点)** | ### 9.4 技术原理图解 #### 9.4.1 三级统计架构 ``` 原始数据(TraceData) │ ├─[流式计算-分钟级]→ TraceMinuteStat/AppMinuteStat(告警数据源) │ └─ 周期:FlowPeriod(默认5秒,可调大至30秒) │ └─ 落盘:SavePeriod(默认60秒,**性能瓶颈**,可调大至180秒) │ └─[批量计算-小时/天级]→ TraceHourStat → TraceDayStat → AppDayStat └─ 周期:BatchPeriod(默认30秒,可调大至60秒) └─ 从下级统计聚合,修正流式计算偏差 ``` #### 9.4.2 延迟队列机制 ``` 统计数据 → 内存累加 → 达到SavePeriod → 批量UPDATE到数据库 (减少锁竞争) (减少IO次数) ``` **性能优化关键**: - 调大SavePeriod:减少UPDATE次数 - 使用累加字段:`UPDATE SET Total=Total+@Total`(减少锁竞争) - 使用压缩表:减少磁盘IO ### 9.5 常用SQL查询 #### 9.5.1 查看队列积压情况 ```sql -- 查看TraceData表数据量(今天) SELECT COUNT(*) FROM TraceData_01 WHERE StatDate = CURDATE(); -- 查看统计表数据量 SELECT (SELECT COUNT(*) FROM TraceMinuteStat WHERE StatTime >= CURDATE()) AS 分钟统计, (SELECT COUNT(*) FROM TraceHourStat WHERE StatTime >= CURDATE()) AS 小时统计, (SELECT COUNT(*) FROM TraceDayStat WHERE StatDate >= CURDATE()) AS 天统计; ``` #### 9.5.2 查看性能指标 ```sql -- 查看慢SQL(执行时间>1秒) SELECT * FROM mysql.slow_log WHERE start_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR) ORDER BY start_time DESC; -- 查看数据库TPS SHOW GLOBAL STATUS LIKE 'Questions'; SHOW GLOBAL STATUS LIKE 'Uptime'; ``` #### 9.5.3 查看埋点统计 ```sql -- 查看应用埋点数量 SELECT AppId, COUNT(*) AS 埋点数 FROM TraceItem GROUP BY AppId ORDER BY 埋点数 DESC; -- 查看最活跃的埋点(今天) SELECT ItemId, Name, SUM(Total) AS 调用次数 FROM TraceDayStat WHERE StatDate = CURDATE() GROUP BY ItemId, Name ORDER BY 调用次数 DESC LIMIT 20; ``` ### 9.6 故障排查清单 #### 9.6.1 CPU占用高 **排查步骤**: 1. 查看当前配置:FlowPeriod、BatchPeriod 2. 查看队列积压:_queue.Count 3. 查看应用数量和埋点数 4. 检查是否有异常流量 **常见原因**: - FlowPeriod太小(如3秒) - 应用数量或埋点数过多 - 突发流量 #### 9.6.2 数据库IO高 **排查步骤**: 1. 查看SavePeriod配置 2. 查看慢SQL 3. 查看数据库TPS 4. 检查是否启用压缩表 **常见原因**: - SavePeriod太小(如30秒) - 数据量过大 - 数据库配置不足 #### 9.6.3 告警延迟大 **排查步骤**: 1. 查看FlowPeriod配置 2. 查看队列积压情况 3. 查看批量计算是否正常 4. 检查网络延迟 **常见原因**: - FlowPeriod太大(如60秒) - 队列积压严重 - 批量计算太慢 ### 9.7 版本历史 | 版本 | 日期 | 说明 | 主要变更 | |------|------|------|----------| | v1.0 | 2026-01-20 | 初始架构文档 | 完整的系统架构说明 | | v1.1 | 2026-02-03 | 性能优化 | 调整统计参数,精简流式计算 | | v2.0 | 2026-02-03 | 文档整合 | 整合优化方案和配置说明,重构为11章 | **v2.0 重大变更**: - **新增第8章**:配置与调优指南(运维必读) - **重构第7章**:性能优化方案与实施 - **整合文档**:合并了《星尘监控性能优化方案》和《星尘监控周期配置优化说明》 - **参数恢复**:将默认周期恢复为保守值(5秒/30秒/60秒),通过配置调优 - **增加场景**:提供5种典型场景的配置建议 - **操作指南**:详细的调优流程和故障排查清单 --- ## 10. 后续计划 ### 10.1 短期计划(1-2个月) | 序号 | 项目 | 状态 | 说明 | |------|------|------|------| | 1 | 参数优化验证 | ✅ 已完成 | 恢复默认配置,支持动态调整 | | 2 | 流式计算精简 | ✅ 已完成 | 仅计算分钟级统计 | | 3 | 配置文档完善 | ✅ 已完成 | 第8章配置与调优指南 | | 4 | 监控指标增强 | 🔄 进行中 | 增加队列长度、计算耗时等监控 | | 5 | 告警延迟优化 | 📝 计划中 | 针对关键应用优化实时性 | ### 10.2 中期计划(3-6个月) | 序号 | 项目 | 优先级 | 说明 | |------|------|--------|------| | 1 | 按需计算实现 | 高 | 用户查看时加速计算 | | 2 | GetOrAddItem优化 | 中 | 延长缓存、批量预热 | | 3 | 智能调度 | 中 | 根据负载动态调整频率 | | 4 | 分布式部署支持 | 低 | 按应用分片处理 | ### 10.3 长期计划(6-12个月) | 序号 | 项目 | 说明 | |------|------|------| | 1 | 时序数据库支持 | 考虑使用InfluxDB或TimescaleDB | | 2 | 流式计算升级 | 使用Kafka Streams或Flink | | 3 | 机器学习告警 | 基于历史数据的智能告警 | | 4 | 全链路追踪 | 支持分布式事务追踪 | ### 10.4 持续改进 - **性能监控**:持续关注CPU、IO、告警延迟等指标 - **用户反馈**:收集运维人员的调优经验 - **最佳实践**:总结不同场景的最优配置 - **文档更新**:根据新功能和经验更新本文档 --- **本文档已完成整合,包含完整的架构说明、性能优化方案和配置调优指南。** **重点章节**: - **第6章**:性能分析与瓶颈识别 - **第7章**:性能优化方案与实施 - **第8章**:配置与调优指南(**运维必读**) **使用建议**: - 开发人员:阅读第2-5章了解系统架构 - 运维人员:重点阅读第6-8章,掌握调优方法 - 管理人员:阅读第1章和第9章版本历史 --- (全文完)