1. 项目概述:基于.NET 9的智能设备监控系统
最近在帮客户部署一套生产环境设备监控方案时,发现市面上现成的工具要么功能过剩要么灵活性不足。于是用.NET 9从头构建了一个轻量级监控工具,核心解决了两个痛点:设备状态变化的实时感知(精确到秒级)和全屏工作时的智能静音策略。这个工具特别适合需要7x24小时监控关键设备的场景,比如实验室仪器、生产线设备或服务器机房。
系统架构上采用三层设计:最底层是设备探针(支持SNMP、HTTP心跳、TCP端口检测等多种协议),中间层用SignalR实现实时通信,展示层用Blazor构建的响应式面板。最让我满意的是离线判断逻辑——不是简单的超时机制,而是结合历史数据动态计算阈值,避免网络波动导致的误报。
2. 核心技术实现解析
2.1 设备状态检测模块
检测逻辑采用多策略组合模式:
csharp复制// 示例检测策略配置
var detector = new DeviceDetectorBuilder()
.AddPingStrategy(interval: TimeSpan.FromSeconds(5))
.AddTcpPortStrategy(ports: new[] { 80, 443 }, timeout: 3000)
.AddCustomHttpCheck("/health", expectedStatus: 200)
.Build();
关键参数说明:
- 心跳间隔:5-30秒可调(生产环境建议10秒)
- 超时阈值:3倍平均响应时间 + 2σ(标准差)
- 离线判定:连续3次检测失败
实测发现单纯依赖ICMP ping不可靠,特别是在跨网段场景下。我们的解决方案是TCP+HTTP组合检测,任一通道成功即视为在线。对于工业设备,还实现了Modbus TCP协议的支持。
2.2 实时通知系统
采用.NET 9新增的Native AOT编译SignalR服务端,消息延迟控制在200ms内:
csharp复制// 状态变更事件处理
services.AddSignalR()
.AddJsonProtocol()
.AddHubOptions<DeviceHub>(options => {
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
options.KeepAliveInterval = TimeSpan.FromSeconds(30);
});
通知渠道矩阵:
| 通知类型 | 触发条件 | 实现方式 |
|---|---|---|
| 桌面弹窗 | 状态变更 | Win32 API + Toast通知 |
| 邮件提醒 | 持续离线>5分钟 | SMTP + Handlebars模板 |
| 短信报警 | 关键设备离线 | Twilio API集成 |
| Teams消息 | 普通状态变更 | Graph API Webhook |
重要提示:避免在循环中直接调用通知API,应该通过消息队列解耦。我们用的是Channel实现的进程内队列,吞吐量可达5000+/秒。
2.3 智能静音系统
全屏检测采用Windows API钩子:
csharp复制[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
bool IsFullScreen() {
var hwnd = GetForegroundWindow();
var rect = new RECT();
GetWindowRect(hwnd, out rect);
return (rect.Right - rect.Left) == Screen.PrimaryScreen.Bounds.Width
&& (rect.Bottom - rect.Top) == Screen.PrimaryScreen.Bounds.Height;
}
静音策略逻辑:
- 检测到全屏应用启动
- 检查进程白名单(视频会议/演示软件)
- 保存当前音量状态
- 渐变降低音量到30%(避免突然静音)
- 窗口退出全屏时恢复原音量
实测数据:在PPT演示场景下,从检测到静音完成耗时约800ms,CPU占用<2%。
3. 部署与优化实践
3.1 性能调优记录
监控50台设备时的资源消耗:
- 内存占用:稳定在120-150MB
- CPU使用率:<5%(i5-8250U)
- 网络流量:约2KB/s(开启压缩后)
关键优化点:
- 设备检测采用轮询+事件混合模式
- 使用MemoryCache做状态缓存
- 日志系统采用异步批处理
- 开启HTTP/2复用连接
3.2 配置示例
appsettings.json关键配置:
json复制{
"Monitoring": {
"CheckInterval": 10,
"OfflineThreshold": 3,
"CriticalDevices": ["PLC-01", "HMI-02"]
},
"Notifications": {
"Email": {
"TemplatePath": "./Templates/alert.html"
}
}
}
4. 典型问题解决方案
4.1 误报问题排查
常见误报场景及应对:
- 网络抖动:启用指数退避重试机制
- 设备忙时无响应:延长检测超时时间
- 防火墙拦截:改用80/443常用端口
- DNS解析失败:本地hosts文件绑定
4.2 内存泄漏处理
通过dotnet-counters发现的线索:
- Gen2 GC持续增长
- Timer实例未释放
根本原因:
未注销的事件处理器:
csharp复制// 错误写法
device.OnStatusChanged += HandleStatusChange;
// 正确写法
device.OnStatusChanged += HandleStatusChange;
...
// 需要时移除
device.OnStatusChanged -= HandleStatusChange;
5. 扩展功能实现
5.1 历史状态追溯
采用环形缓冲区存储最近状态:
csharp复制public class DeviceStateHistory {
private readonly ConcurrentQueue<DeviceState> _queue = new();
private readonly int _maxItems = 100;
public void AddState(DeviceState state) {
_queue.Enqueue(state);
if (_queue.Count > _maxItems) {
_queue.TryDequeue(out _);
}
}
}
5.2 移动端适配
通过PWA实现手机端监控:
- 添加manifest.json
- 配置Service Worker缓存策略
- 使用MediaQuery适配不同屏幕
- 实现后台同步功能
在iOS上的实测表现:
- 通知延迟:约1.2秒
- 电池影响:8小时耗电约3%
- 离线支持:最长4小时数据保留
这套系统经过三个月的生产环境验证,在50台设备规模下实现了99.98%的检测准确率。最关键的收获是状态判断算法需要持续优化——我们后来加入了机器学习模块,用历史数据训练出每台设备的正常行为模式,进一步降低了误报率。