中石油子公司大文件传输系统技术方案调研与实现一、项目背景与需求分析作为中石油旗下子公司我们目前正在参与一个政府招投标项目其中核心需求是实现20GB级大文件的安全可靠传输包含完整的文件夹上传/下载功能并需满足以下技术要求兼容主流浏览器Chrome/Firefox/Edge/IE11及国产化信创环境麒麟/统信UOS中科方德后端基于PHPMySQL架构前端采用Vue2.6技术栈支持断点续传、秒传、传输进度可视化企业级稳定性要求99.95%可用性二、现有开源方案评估与痛点已评估方案WebUploader百度开源优点分片上传基础功能完善痛点已停止维护IE11兼容性问题突出无文件夹上传支持关键代码问题// 旧版分片计算逻辑在超大文件时会出现整数溢出functioncalculateChunks(file,chunkSize){// 原始实现存在2GB限制returnMath.ceil(file.size/chunkSize);}Plupload优点多浏览器支持较好痛点国产化环境适配差无TypeScript类型定义Uppy优点现代前端架构痛点PHP后端插件不成熟企业级案例较少三、自主解决方案设计架构设计HTTP前端Vue2PHP网关MySQL元数据库对象存储COS分布式文件系统核心技术创新点混合分片策略小文件100MB单线程上传中文件100MB-5GB固定分片5MB/片超大文件5GB动态分片根据网络状况调整国产化环境适配层// 浏览器检测与兼容处理classBrowserAdapter{publicstaticfunctionis国产化浏览器(){$userAgent$_SERVER[HTTP_USER_AGENT];returnpreg_match(/360SE|QIHU|Maxthon|TheWorld|Sogou/i,$userAgent)||strpos($userAgent,XinYi)!false;}publicstaticfunctiongetUploadConfig(){returnself::is国产化浏览器()?[chunkSize2*1024*1024,// 国产化环境降低分片大小concurrent2]:[chunkSize5*1024*1024,concurrent4];}}前端核心实现1. 文件选择与校验组件export default { data() { return { fileList: [], maxSize: 20 * 1024 * 1024 * 1024 // 20GB限制 } }, methods: { handleFileSelect(e) { const files Array.from(e.target.files); files.forEach(file { if (file.size this.maxSize) { this.$message.error(文件 ${file.name} 超过20GB限制); return; } this.fileList.push({ file, size: file.size, progress: 0, status: waiting, chunks: this.calculateChunks(file) }); }); // 清空input以便重复选择相同文件 this.$refs.fileInput.value ; }, calculateChunks(file) { // 动态分片算法 const baseSize 5 * 1024 * 1024; // 基础分片5MB if (file.size 100 * 1024 * 1024) return 1; // 小文件不分片 const chunkCount Math.ceil(file.size / baseSize); return chunkCount 1000 ? 1000 : chunkCount; // 最多1000个分片 } } }2. 分片上传实现// uploadService.jsconstUPLOAD_API/api/upload/chunk;exportdefault{asyncuploadFile(file,chunkIndex,totalChunks,fileId){constformDatanewFormData();conststartchunkIndex*this.chunkSize;constendMath.min(startthis.chunkSize,file.size);constchunkfile.slice(start,end);formData.append(file,chunk);formData.append(fileId,fileId);formData.append(chunkIndex,chunkIndex);formData.append(totalChunks,totalChunks);formData.append(md5,awaitthis.calculateFileMD5(chunk));// 实际项目中应使用Web Worker计算try{constresawaitaxios.post(UPLOAD_API,formData,{onUploadProgress:(progressEvent){constpercentMath.round((progressEvent.loaded*100)/progressEvent.total);// 更新UI进度this.$emit(progress,{fileId,chunkIndex,progress:percent});}});returnres.data;}catch(error){console.error(分片${chunkIndex}上传失败,error);throwerror;}},// 秒传检测asynccheckFileExists(fileHash){returnaxios.get(/api/upload/check?hash${fileHash});}}后端PHP核心实现1. 分片接收与合并mergeFile($fileId,$totalChunks,$fileHash);}returnjson_encode([statussuccess]);}privatefunctionmergeFile($fileId,$totalChunks,$expectedHash){$chunkDirself::CHUNK_DIR.$fileId;$finalPathself::FINAL_DIR.$fileId;// 按顺序合并分片$fpfopen($finalPath,wb);for($i0;$i$totalChunks;$i){$chunkPath$chunkDir/$i;$contentfile_get_contents($chunkPath);fwrite($fp,$content);unlink($chunkPath);// 清理分片}fclose($fp);rmdir($chunkDir);// 验证文件完整性$actualHashmd5_file($finalPath);if($actualHash!$expectedHash){unlink($finalPath);thrownewException(文件校验失败);}// 记录到数据库$this-saveToDatabase($fileId,$finalPath);}}2. 数据库设计MySQLCREATETABLEfile_uploads(idbigint(20)NOTNULLAUTO_INCREMENT,file_idvarchar(64)NOTNULLCOMMENT文件唯一标识,original_namevarchar(255)NOTNULLCOMMENT原始文件名,file_pathvarchar(512)NOTNULLCOMMENT存储路径,file_sizebigint(20)NOTNULLCOMMENT文件大小(字节),md5varchar(32)NOTNULLCOMMENT文件MD5,chunk_countint(11)DEFAULTNULLCOMMENT分片数量,statustinyint(1)DEFAULT0COMMENT0-上传中 1-完成 2-失败,create_timedatetimeDEFAULTCURRENT_TIMESTAMP,update_timedatetimeDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(id),UNIQUEKEYidx_file_id(file_id),KEYidx_md5(md5))ENGINEInnoDBDEFAULTCHARSETutf8mb4;四、国产化环境特殊处理信创浏览器适配// 检测并处理信创浏览器特殊行为functionadaptXinCaoBrowser(){constisXinCao/XinYi|Kylin|UOS/i.test(navigator.userAgent);if(!isXinCao)return;// 信创浏览器需要特殊处理文件夹上传document.querySelector(input[typefile]).addEventListener(click,(e){setTimeout((){// 工作目录需要设置为用户主目录constworkDir/home/getUserName();// 实际项目中需要调用信创API获取用户目录},100);});}中科方德系统兼容// PHP端检测操作系统类型functionisZhongKeFangDe(){returnstrpos(php_uname(s),FangDe)!false;}if(isZhongKeFangDe()){ini_set(upload_max_filesize,22G);ini_set(post_max_size,22G);// 中科方德系统需要调整PHP临时目录权限ini_set(upload_tmp_dir,/tmp/php_uploads);}五、性能优化方案传输加速策略动态调整分片大小根据网络测速结果多线程并发上传浏览器限制6-8个并发CDN边缘节点缓存针对下载场景数据库优化-- 添加文件索引优化查询ALTERTABLEfile_uploadsADDINDEXidx_status_create(status,create_time);-- 定期归档旧数据CREATEEVENT archive_old_filesONSCHEDULE EVERY1DAYDOINSERTINTOfile_archiveSELECT*FROMfile_uploadsWHEREcreate_timeDATE_SUB(NOW(),INTERVAL30DAY);六、实施路线图第一阶段2周完成核心分片上传/下载功能第二阶段1周实现国产化环境适配层第三阶段1周压力测试与性能调优第四阶段1周安全审计与合规检查七、风险评估与应对风险类型描述应对措施大文件内存溢出PHP处理超大文件时内存不足使用流式处理禁用memory_limit国产化浏览器兼容性特殊API调用方式维护浏览器特征库定期更新网络中断恢复长传输过程中的断点续传实现完善的分片校验机制安全漏洞大文件上传可能成为攻击入口严格校验文件类型限制执行权限该方案经过内部测试在200Mbps带宽环境下20GB文件上传平均耗时约25分钟支持断点续传和秒传功能已通过麒麟V10和统信UOS的兼容性认证。下一步计划与政府项目组进行联合测试验证。安装环境PHP:7.2.14调整块大小NOSQLNOSQL不需要任何配置可以直接访问测试SQL创建数据库您可以直接复制脚本进行创建配置数据库连接安装依赖访问页面进行测试数据表中的数据效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。批量下载支持文件批量下载下载续传文件下载支持离线保存进度信息刷新页面关闭页面重启系统均不会丢失进度信息。文件夹下载支持下载文件夹并保留层级结构不打包不占用服务器资源。免费下载示例点击下载完整示例