一个基于 .NET 开发的高性能、高可靠工业数据采集系统,专为 PLC(可编程逻辑控制器)场景设计。支持 .NET 8.0 和 .NET 10.0 两个 LTS 版本,采用 WAL-first(Write-Ahead Logging)架构,确保数据零丢失,并提供多 PLC 并行采集、条件触发、批量读取等高级功能。
核心特性
- WAL-first 架构:先写本地 Parquet 日志,再写入时序数据库,保障数据不丢
- 多 PLC 并行采集:支持 Modbus、Beckhoff ADS、汇川、三菱、西门子等主流协议
- 条件触发采集:支持边沿触发(Rising/Falling Edge)、值变化触发等智能模式
- 批量读取优化:减少网络往返,提升吞吐效率
- 配置热更新:JSON 配置 + 文件监听,无需重启服务
- 实时监控:内置 Prometheus 指标 + Vue3 可视化界面
- 双存储策略:InfluxDB(主存) + Parquet(本地 WAL)
- 自动重试机制:网络异常自动重连,失败数据由 RetryWorker 重传
系统架构
整体架构
PLC Device
│
▼
Heartbeat Monitor Layer
│
▼
Data Acquisition Layer (ChannelCollector)
│
▼
Queue Service Layer (LocalQueueService)
│
▼
Storage Layer → WAL (Parquet) → InfluxDB
│ ▲
└── RetryWorker ←┘ (失败重试)
核心数据流
- 采集:PLC → ChannelCollector
- 聚合:LocalQueueService 按 BatchSize 缓存
- 持久化:立即写入 Parquet WAL 文件、同步写入 InfluxDB
- 清理:两者成功 → 删除 WAL;任一失败 → 保留 WAL,由 RetryWorker 重试
项目结构
├── Application/ # 应用层(接口定义)
├── Domain/ # 领域模型(数据结构、事件)
├── Infrastructure/ # 基础设施(PLC 客户端、存储、指标)
├── Gateway/ # Web 网关(API + 配置 + 前端)
├── Simulator/ # PLC 模拟器(用于测试)
项目使用
环境要求
- .NET 8.0 或 .NET 10.0 SDK(LTS 版本)
- InfluxDB 2.x(可选,用于时序存储)
- 支持的 PLC(或使用内置模拟器)
版本建议
.NET 10.0:最新 LTS,支持至 2028 年(推荐新项目)
.NET 8.0:稳定 LTS,支持至 2026 年(推荐生产环境)
安装与运行
# 克隆项目
# 恢复依赖
dotnet restore
# 运行(默认框架)
dotnet run --project xx.Gateway
# 指定框架运行
dotnet run -f net10.0 --project xx.Gateway
使用 PLC 模拟器(无需真实设备)
# 启动模拟器(模拟三菱 PLC)
cd xx.Simulator
dotnet run
模拟器提供:
- 心跳寄存器(D100 自增)
- 7 个传感器指标(温度、压力、电流等)
- 条件触发测试(基于生产序号)
- 交互式命令(set/get/info)
配置说明
设备配置示例 (M01C123.json)
{
"IsEnabled": true,
"PLCCode": "PLC01",
"Host": "192.168.1.100",
"Port": 502,
"Type": "Mitsubishi",
"Channels": [
{
"Measurement": "temperature",
"ChannelCode": "PLC01C01",
"AcquisitionInterval": 100,
"AcquisitionMode": "Conditional",
"EnableBatchRead": true,
"BatchReadRegister": "D200",
"BatchReadLength": 20,
"DataPoints": [
{
"FieldName": "temp_value",
"Register": "D200",
"Index": 0,
"DataType": "short",
"EvalExpression": "value * 0.1"
}
],
"ConditionalAcquisition": {
"Register": "D210",
"DataType": "short",
"StartTriggerMode": "RisingEdge",
"EndTriggerMode": "FallingEdge"
}
}
]
}
注意:RisingEdge / FallingEdge 指数值增减变化(非 0/1 跳变),适用于计数器、状态码等场景。
InfluxDB 映射规则
| 配置项 |
InfluxDB 结构 |
示例 |
| Measurement |
Measurement |
sensor |
| PLCCode |
Tag plc_code |
M01C123 |
| ChannelCode |
Tag channel_code |
M01C01 |
| FieldName |
Field |
up_temp=250i |
| 采集时间 |
Timestamp |
1705312200000000000 |
| 条件周期 ID |
Field cycle_id |
"guid-xxx" |
Line Protocol 示例:
sensor,plc_code=M01C123,channel_code=M01C01,event_type=Start up_temp=250i,cycle_id="..." 1705312200000000000
API 使用示例
# 获取 Prometheus 指标
curl http://localhost:8000/metrics
# 获取 JSON 格式指标
curl http://localhost:8000/api/metrics-data
# 查询 PLC 连接状态
curl http://localhost:8000/api/xx/GetPLCConnectionStatus
C# 写入示例
var request = new PLCWriteRequest {
PLCCode = "M01C123",
Items = new[] { new PLCWriteItem { Address = "D300", DataType = "short", Value = 100 } }
};
await httpClient.PostAsJsonAsync("/api/xx/WriteRegister", request);
核心模块说明
PLC 客户端支持
| 协议 |
实现类 |
| 三菱 |
MitsubishiPLCClientService |
| 汇川 |
InovancePLCClientService |
| 倍福 ADS |
BeckhoffAdsPLCClientService |
| 西门子 |
SiemensPLClientService |
关键服务
- ChannelCollector:负责按通道采集数据,支持条件/持续模式
- InfluxDbDataStorageService:批量写入 InfluxDB,带错误回调与重试
- MetricsCollector:暴露采集延迟、队列深度、写入成功率等指标
数据处理流程
- 正常路径:采集 → 队列聚合 → WAL 写入 → InfluxDB 写入 → WAL 清理
- 异常路径:
- 网络断开 → 心跳监控 + 自动重连
- 存储失败 → WAL 保留 → ParquetRetryWorker 定期重试
性能建议
| 参数 |
推荐值 |
说明 |
| BatchSize |
10–50 |
平衡吞吐与延迟 |
| AcquisitionInterval |
100–500 ms |
根据 PLC 负载调整 |
| HeartbeatPollingInterval |
5000 ms |
连接健康检查频率 |
总结
这是一个面向工业自动化场景的高并发 PLC 数据采集系统,基于 .NET 8/10 开发,专为零丢失的数据采集需求设计。
系统采用 WAL-first(预写日志)架构,确保在任何异常情况下数据不丢失;支持多种主流 PLC 协议(如三菱、西门子、汇川、倍福 ADS、Modbus),并提供条件触发、批量读取、配置热更新等高级功能。通过双存储策略(InfluxDB + Parquet)与自动重试机制,系统在保障可靠性的同时兼顾性能与可运维性。内置 Prometheus 指标暴露与 Web 监控界面,便于集成到 DevOps 体系中。
整体采用分层模块化设计,具备良好的扩展性和维护性,适用于智能制造、能源监控、设备物联等工业物联网(IIoT)场景。如果你对如何用 .NET 构建类似的工业级系统架构感兴趣,欢迎到 云栈社区 交流探讨。