节点在线、应用在线、配置在线使用令牌查询
|
# 星尘监控系统架构文档
## 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章版本历史
---
(全文完)
|