1. 项目背景与核心需求
在能源化工行业的生产监控系统中,每天都会产生大量高精度传感器数据、工艺参数记录和质检报告。这些生产数据文件通常体积庞大(单个CSV或二进制文件可达数百MB),且需要实时上传至中央数据库进行分析。传统表单提交方式在面对GB级文件时,常因网络波动导致传输中断,而重新上传既浪费带宽又影响生产时效性。
我们基于百度WebUploader前端组件,实现了以下核心功能:
- 秒传验证:通过文件指纹识别技术,服务器已有文件无需重复传输
- 断点续传:网络中断后可从断开位置继续上传,而非重新开始
- 分块传输:将大文件切割为多个小块并行上传,提升传输效率
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体流程设计
mermaid复制graph TD
A[前端初始化] --> B[生成文件指纹]
B --> C{查询服务器是否存在}
C -->|已存在| D[秒传完成]
C -->|不存在| E[分块上传]
E --> F[网络中断?]
F -->|是| G[记录已传块]
F -->|否| H[合并文件]
2.2 关键组件选型
| 组件 | 版本 | 作用 |
|---|---|---|
| WebUploader | 4.1.5 | 前端分块上传控制 |
| SparkMD5 | 0.3.1 | 前端文件指纹计算 |
| Node.js | 16.x | 后端分块接收服务 |
| MongoDB | 5.0 | 存储上传状态记录 |
特别注意:生产环境建议使用Redis替代MongoDB做状态缓存,因化工数据高频写入场景更适合内存数据库
3. 核心代码实现
3.1 前端秒传验证
javascript复制// 生成文件指纹(使用WebWorker避免界面卡顿)
function generateFileMd5(file) {
return new Promise((resolve) => {
const worker = new Worker('spark-md5-worker.js');
worker.postMessage({ file });
worker.onmessage = (e) => resolve(e.data.md5);
});
}
// 检查服务器是否存在相同文件
async function checkFileExist(md5) {
const res = await fetch(`/api/check?md5=${md5}`);
return res.json();
}
3.2 分块上传控制
javascript复制const uploader = WebUploader.create({
server: '/api/upload',
chunked: true,
chunkSize: 5 * 1024 * 1024, // 5MB/块
threads: 3 // 并行上传数
});
uploader.on('uploadSuccess', (file, response) => {
if (response.needMerge) {
mergeFile(file.md5, response.chunks);
}
});
3.3 后端断点记录(Node.js示例)
javascript复制// 记录已接收分块
app.post('/api/upload', (req, res) => {
const { md5, chunkIndex } = req.query;
// 将分块写入临时目录
const ws = fs.createWriteStream(`./temp/${md5}_${chunkIndex}`);
req.pipe(ws);
// 更新Redis记录
redisClient.sadd(`upload:${md5}`, chunkIndex);
});
4. 生产环境优化策略
4.1 化工数据特殊处理
- 二进制文件压缩:对PLC采集的原始二进制数据启用LZ4压缩
- CRC校验增强:每个分块增加32位CRC校验码,防止传输污染
- 自动重试策略:根据化工车间网络质量动态调整重试间隔
4.2 性能对比测试
| 文件大小 | 传统方式 | 分块上传 | 提升效果 |
|---|---|---|---|
| 100MB | 2分18秒 | 41秒 | 230% |
| 500MB | 经常失败 | 3分12秒 | 可完成 |
| 1GB | 无法上传 | 6分45秒 | 可完成 |
5. 异常处理方案
5.1 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 秒传误判 | 服务器时钟不同步 | 部署NTP时间同步服务 |
| 分块丢失 | 车间网络抖动 | 启用UDP心跳检测 |
| 合并失败 | 磁盘空间不足 | 增加inotify监控 |
5.2 容灾方案
javascript复制// 断网自动保存状态
window.addEventListener('offline', () => {
const state = uploader.getStats();
localStorage.setItem('uploadState', JSON.stringify(state));
});
// 恢复网络后继续
window.addEventListener('online', async () => {
const state = JSON.parse(localStorage.getItem('uploadState'));
if (state) {
await resumeUpload(state);
}
});
6. 安全防护措施
-
工业协议加固:
- 对Modbus TCP数据包进行AES-256加密
- 每个上传请求必须携带PLC设备签名
-
防注入方案:
javascript复制// 文件名净化处理 function sanitizeFilename(name) { return name.replace(/[^a-zA-Z0-9\-_\.]/g, ''); } -
审计日志:
- 记录每个操作员的文件上传行为
- 与DCS系统操作日志联动分析
7. 实际部署效果
在某石化企业烯烃分厂部署后:
- 每日2000+个传感器数据文件(平均300MB/个)上传成功率从68%提升至99.7%
- 网络带宽占用峰值降低62%
- 操作员误操作导致的数据重传减少85%
关键收获:通过将分块大小调整为5MB(原方案2MB),在化工企业常见的4G专网环境下取得了最佳传输效率。过小的分块会导致TCP握手开销占比过高,过大的分块则容易因网络波动中断。
