170 lines
5.0 KiB
JavaScript
170 lines
5.0 KiB
JavaScript
![]() |
#!/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);
|
|||
|
});
|