AWS Lambda(Node.js)解压/tmp中Zip文件时函数无错误终止问题
问题
我在Node.js编写的AWS Lambda函数中将Zip文件下载到/tmp目录,但尝试解压这些文件时,函数在调用decompress后停止执行,且无任何错误信息。相关代码片段如下:
主逻辑代码
for (let delivery of products.deliveries) { for (let zfile of delivery.files) { // console.log({ zip_file }); var folderName = zfile.fileName.replace(".zip", ""); var fileNameZip = `/tmp/${zfile.fileName}`; let exist = await s3.listObjectsV2({ Bucket: someName, Prefix: folderName}).promise(); if (exist.KeyCount) { await P.downloadFile( token, fileNameZip, delivery.deliveryId, delivery.files[0].fileId, zfile.fileSize ); await Puller.unzipFile(fileNameZip); console.log("THIS HAPPENS") await Puller.extractFolder(fileNameZip, `/tmp/${folderName}`); console.log("DOES NOT HAPPEN") }
extractFolder方法代码
public async extractFolder(fileName: string, folderName: string): Promise<boolean> { try { console.log(`extracting ${fileName}`); console.log(`extracting into folder ${folderName}`); await decompress(fileName, folderName); console.log('LOG NOT SHOWN') return true } catch (error) { console.log('error', error) return false } }
解决方案
以下是几个具体的排查和解决方向:
检查Lambda的/tmp目录空间限制
AWS Lambda的/tmp目录空间和函数内存绑定,默认配置下部分运行时仅512MB。如果解压后的文件超出可用空间,部分解压库会静默终止而非抛出错误。- 调用decompress前添加代码查看/tmp使用情况:
const { execSync } = require('child_process'); console.log('Tmp目录占用:', execSync('df -h /tmp').toString()); - 调高Lambda函数的内存配置,内存越大对应/tmp空间越大(例如1GB内存对应1GB/tmp空间)。
- 调用decompress前添加代码查看/tmp使用情况:
验证decompress库的兼容性与参数
部分Zip格式(加密、分卷、特殊路径)可能导致decompress库异常,可尝试:- 添加强制处理参数:
await decompress(fileName, folderName, { filter: () => true, map: file => { file.path = file.path.replace(/^\//, ''); // 避免生成绝对路径引发权限问题 return file; } }); - 替换为更稳定的解压库(如
adm-zip)测试:import AdmZip from 'adm-zip'; public async extractFolder(fileName: string, folderName: string): Promise<boolean> { try { console.log(`extracting ${fileName}`); console.log(`extracting into folder ${folderName}`); const zip = new AdmZip(fileName); zip.extractAllTo(folderName, true); // true表示覆盖现有文件 console.log('解压完成'); return true; } catch (error) { console.log('error', error); return false; } }
- 添加强制处理参数:
确认下载的Zip文件完整性
下载的文件可能损坏导致解压失败,添加校验步骤:const fs = require('fs').promises; const stats = await fs.stat(fileNameZip); console.log(`已下载文件大小: ${stats.size}, 预期大小: ${zfile.fileSize}`); if (stats.size !== zfile.fileSize) { console.error('文件下载不完整'); continue; }排查Lambda超时与未捕获异常
- 临时调高Lambda函数的超时时间(如设置为5分钟),避免解压耗时过长被强制终止。
- 添加全局未捕获异常监听,捕获潜在的Promise rejection:
process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', promise, '原因:', reason); });
内容的提问来源于stack exchange,提问作者Meto twi8
相关产品推荐
相关产品推荐

