#!/usr/bin/env node /** * S3存储调试脚本 * 用于快速诊断S3存储连接问题 */ // 检查是否有.env文件,如果有就加载 try { require('dotenv').config(); } catch (e) { console.log('No dotenv found, using environment variables directly'); } async function debugS3() { console.log('🔍 S3存储调试开始...\n'); // 1. 检查环境变量 console.log('📋 环境变量检查:'); const requiredVars = { STORAGE_TYPE: process.env.STORAGE_TYPE, S3_BUCKET: process.env.S3_BUCKET, S3_ACCESS_KEY_ID: process.env.S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY: process.env.S3_SECRET_ACCESS_KEY, S3_REGION: process.env.S3_REGION, S3_ENDPOINT: process.env.S3_ENDPOINT, }; for (const [key, value] of Object.entries(requiredVars)) { if (key.includes('SECRET')) { console.log(` ${key}: ${value ? '✅ 已设置' : '❌ 未设置'}`); } else { console.log(` ${key}: ${value || '❌ 未设置'}`); } } if (process.env.STORAGE_TYPE !== 's3') { console.log('\n❌ STORAGE_TYPE 不是 s3,无法测试S3连接'); return; } const missingVars = ['S3_BUCKET', 'S3_ACCESS_KEY_ID', 'S3_SECRET_ACCESS_KEY'].filter((key) => !process.env[key]); if (missingVars.length > 0) { console.log(`\n❌ 缺少必要的环境变量: ${missingVars.join(', ')}`); console.log('请设置这些环境变量后重试'); return; } console.log('\n✅ 环境变量检查通过\n'); // 2. 测试AWS SDK加载 console.log('📦 加载AWS SDK...'); try { const { S3 } = require('@aws-sdk/client-s3'); console.log('✅ AWS SDK加载成功\n'); // 3. 创建S3客户端 console.log('🔧 创建S3客户端...'); const config = { region: process.env.S3_REGION || 'auto', credentials: { accessKeyId: process.env.S3_ACCESS_KEY_ID, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY, }, }; if (process.env.S3_ENDPOINT) { config.endpoint = process.env.S3_ENDPOINT; } if (process.env.S3_FORCE_PATH_STYLE === 'true') { config.forcePathStyle = true; } console.log('S3客户端配置:', { region: config.region, endpoint: config.endpoint || '默认AWS端点', forcePathStyle: config.forcePathStyle || false, }); const s3Client = new S3(config); console.log('✅ S3客户端创建成功\n'); // 4. 测试bucket访问 console.log('🪣 测试bucket访问...'); try { await s3Client.headBucket({ Bucket: process.env.S3_BUCKET }); console.log('✅ Bucket访问成功'); } catch (error) { console.log(`❌ Bucket访问失败: ${error.message}`); console.log('错误详情:', error); if (error.name === 'NotFound') { console.log(' 💡 提示: Bucket不存在,请检查bucket名称'); } else if (error.name === 'Forbidden') { console.log(' 💡 提示: 访问被拒绝,请检查访问密钥权限'); } else if (error.message.includes('getaddrinfo ENOTFOUND')) { console.log(' 💡 提示: DNS解析失败,请检查endpoint设置'); } return; } // 5. 测试列出对象 console.log('\n📂 测试列出对象...'); try { const result = await s3Client.listObjectsV2({ Bucket: process.env.S3_BUCKET, MaxKeys: 5, }); console.log(`✅ 列出对象成功,共有 ${result.KeyCount || 0} 个对象`); if (result.Contents && result.Contents.length > 0) { console.log(' 前几个对象:'); result.Contents.slice(0, 3).forEach((obj, index) => { console.log(` ${index + 1}. ${obj.Key} (${obj.Size} bytes)`); }); } } catch (error) { console.log(`❌ 列出对象失败: ${error.message}`); console.log('错误详情:', error); return; } // 6. 测试创建multipart upload console.log('\n🚀 测试创建multipart upload...'); const testKey = `test-multipart-${Date.now()}`; let uploadId; try { const createResult = await s3Client.createMultipartUpload({ Bucket: process.env.S3_BUCKET, Key: testKey, Metadata: { test: 'debug-script' }, }); uploadId = createResult.UploadId; console.log(`✅ Multipart upload创建成功,UploadId: ${uploadId}`); // 清理测试upload await s3Client.abortMultipartUpload({ Bucket: process.env.S3_BUCKET, Key: testKey, UploadId: uploadId, }); console.log('✅ 测试upload已清理'); } catch (error) { console.log(`❌ Multipart upload创建失败: ${error.message}`); console.log('错误详情:', error); return; } console.log('\n🎉 S3连接测试全部通过!S3存储应该可以正常工作。'); console.log('\n💡 如果上传仍然失败,请检查:'); console.log('1. 网络连接是否稳定'); console.log('2. 防火墙是否阻止了连接'); console.log('3. S3服务是否有临时问题'); console.log('4. 查看应用日志中的详细错误信息'); } catch (error) { console.log(`❌ AWS SDK加载失败: ${error.message}`); console.log('请确保已安装 @aws-sdk/client-s3 包:'); console.log('npm install @aws-sdk/client-s3'); } } // 运行调试 debugS3().catch((error) => { console.error('调试脚本出错:', error); process.exit(1); });