Rumah > Artikel > hujung hadapan web > Mengoptimumkan Muat Naik Fail Besar: Muat Naik Berbilang Bahagian Sebelah Pelanggan yang Selamat ke AWS S3
Memuat naik fail besar ke awan boleh menjadi mencabar — gangguan rangkaian, pengehadan penyemak imbas dan saiz fail yang besar boleh mengganggu proses dengan mudah. Amazon S3 (Perkhidmatan Storan Mudah) ialah perkhidmatan storan awan berasaskan web yang boleh skala, berkelajuan tinggi, direka untuk sandaran dalam talian dan mengarkibkan data dan aplikasi. Walau bagaimanapun, memuat naik fail besar ke S3 memerlukan pengendalian yang teliti untuk memastikan kebolehpercayaan dan prestasi.
Masukkan muat naik berbilang bahagian AWS S3: penyelesaian berkuasa yang memecahkan fail besar kepada bahagian yang lebih kecil, membolehkan muat naik yang lebih pantas dan lebih dipercayai dengan menangani setiap bahagian secara bebas malah memuat naik bahagian secara selari. Kaedah ini bukan sahaja mengatasi had saiz fail (S3 memerlukan muat naik berbilang bahagian untuk fail yang lebih besar daripada 5GB) tetapi juga meminimumkan risiko kegagalan, menjadikannya sesuai untuk aplikasi yang memerlukan muat naik fail yang lancar dan mantap.
Dalam panduan ini, kami akan membongkar selok-belok muat naik berbilang bahagian pelanggan ke S3, menunjukkan kepada anda sebab ia merupakan pilihan bijak untuk mengendalikan fail besar, cara untuk menyediakannya dan berjalan dengan selamat serta cabaran yang perlu diperhatikan. keluar untuk. Saya akan memberikan arahan langkah demi langkah, contoh kod dan amalan terbaik untuk membantu anda melaksanakan penyelesaian muat naik fail sebelah pelanggan yang boleh dipercayai.
Bersedia untuk meningkatkan pengalaman memuat naik fail anda? Mari selami!
Apabila mereka bentuk sistem muat naik fail, anda mempunyai dua pilihan utama: memuat naik fail melalui pelayan anda (sebelah pelayan) atau memuat naik fail terus daripada klien ke S3 (sebelah klien). Setiap pendekatan ada kebaikan dan keburukannya.
Keselamatan Dipertingkat: Semua muat naik diuruskan oleh pelayan, memastikan kelayakan AWS selamat.
Pengendalian Ralat yang Lebih Baik: Pelayan boleh mengurus percubaan semula, pengelogan dan pengendalian ralat dengan lebih mantap.
Pemprosesan Berpusat: Fail boleh disahkan, diproses atau ditukar pada pelayan sebelum disimpan dalam S3.
Muatan Pelayan yang Lebih Tinggi: Muat naik yang besar menggunakan sumber pelayan (CPU, memori, lebar jalur), yang boleh memberi kesan kepada prestasi dan meningkatkan kos operasi.
Potensi Kesesakan: Pelayan boleh menjadi satu titik kegagalan atau kesesakan prestasi semasa trafik muat naik tinggi, yang membawa kepada muat naik perlahan atau masa henti.
Kos Peningkatan: Mengendalikan muat naik di bahagian pelayan mungkin memerlukan penskalaan infrastruktur anda untuk mengendalikan beban puncak, meningkatkan perbelanjaan operasi.
Muatan Pelayan Dikurangkan: Fail dihantar terus dari peranti pengguna ke S3, membebaskan sumber pelayan.
Kelajuan yang Dipertingkat: Pengguna mengalami muat naik yang lebih pantas kerana mereka memintas pelayan aplikasi.
Kecekapan Kos: Menghapuskan keperluan untuk infrastruktur pelayan untuk mengendalikan muat naik yang besar, yang berpotensi mengurangkan kos.
Skalabiliti: Sesuai untuk menskalakan muat naik fail tanpa menekankan pelayan bahagian belakang.
Risiko Keselamatan: Memerlukan pengendalian teliti bukti kelayakan dan kebenaran AWS. URL yang ditetapkan mesti dijana dengan selamat untuk menghalang akses tanpa kebenaran.
Kawalan Terhad: Kurang pengawasan sebelah pelayan terhadap muat naik; pengendalian ralat dan cuba semula selalunya diuruskan pada klien.
Kekangan Pelayar: Penyemak imbas mempunyai had memori dan API, yang boleh menghalang pengendalian fail yang sangat besar atau menjejaskan prestasi pada peranti kelas bawah.
Melaksanakan muat naik bahagian pelanggan dengan selamat melibatkan penyelarasan antara aplikasi bahagian hadapan anda dan perkhidmatan bahagian belakang yang selamat. Peranan utama perkhidmatan bahagian belakang adalah untuk menjana URL yang ditetapkan, membolehkan pelanggan memuat naik fail terus ke S3 tanpa mendedahkan bukti kelayakan AWS yang sensitif.
Untuk melaksanakan muat naik sebelah pelanggan dengan berkesan, anda memerlukan:
Seni bina ini memastikan operasi sensitif dikendalikan dengan selamat pada bahagian belakang, manakala bahagian hadapan menguruskan proses muat naik.
URL yang ditetapkan membenarkan pelanggan berinteraksi dengan S3 secara langsung, melakukan operasi seperti memuat naik fail tanpa memerlukan bukti kelayakan AWS di sisi klien. Mereka selamat kerana:
Buat kelas perkhidmatan pada pelayan anda yang bertanggungjawab untuk:
a. Menentukan baldi dan rantau S3
b. Mewujudkan bukti kelayakan AWS dengan selamat.
c. Menyediakan kaedah untuk menjana URL yang ditetapkan dan mengurus muat naik berbilang bahagian.
// services/S3UploadService.js import { S3Client, CreateMultipartUploadCommand, CompleteMultipartUploadCommand, UploadPartCommand, AbortMultipartUploadCommand, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, } from '@aws-sdk/client-s3'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; // Import credential providers import { fromIni, fromInstanceMetadata, fromEnv, fromProcess, } from '@aws-sdk/credential-providers'; export class S3UploadService { constructor() { this.s3BucketName = process.env.S3_BUCKET_NAME; this.s3Region = process.env.S3_REGION; this.s3Client = new S3Client({ region: this.s3Region, credentials: this.getS3ClientCredentials(), }); } // Method to generate AWS credentials securely getS3ClientCredentials() { if (process.env.NODE_ENV === 'development') { // In development, use credentials from environment variables return fromEnv(); } else { // In production, use credentials from EC2 instance metadata or another secure method return fromInstanceMetadata(); } } // Generate a presigned URL for single-part upload (PUT), download (GET), or deletion (DELETE) async generatePresignedUrl(key, operation) { let command; switch (operation) { case 'PUT': command = new PutObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; case 'GET': command = new GetObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; case 'DELETE': command = new DeleteObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; default: throw new Error(`Invalid operation "${operation}"`); } // Generate presigned URL return await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); // Expires in 1 hour } // Methods for multipart upload async createMultipartUpload(key) { const command = new CreateMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, }); const response = await this.s3Client.send(command); return response.UploadId; } async generateUploadPartUrl(key, uploadId, partNumber) { const command = new UploadPartCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, PartNumber: partNumber, }); return await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); } async completeMultipartUpload(key, uploadId, parts) { const command = new CompleteMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, MultipartUpload: { Parts: parts }, }); return await this.s3Client.send(command); } async abortMultipartUpload(key, uploadId) { const command = new AbortMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, }); return await this.s3Client.send(command); } }
Nota: Pastikan bukti kelayakan AWS anda diurus dengan selamat. Dalam pengeluaran, adalah disyorkan untuk menggunakan peranan IAM yang dilampirkan pada kejadian EC2 atau tugas ECS anda, berbanding kelayakan pengekodan keras atau menggunakan pembolehubah persekitaran.
Buat titik akhir API di bahagian belakang anda untuk mengendalikan permintaan daripada bahagian hadapan. Titik akhir ini akan menggunakan S3UploadService untuk melakukan tindakan.
// controllers/S3UploadController.js import { S3UploadService } from '../services/S3UploadService'; const s3UploadService = new S3UploadService(); export const generatePresignedUrl = async (req, res, next) => { try { const { key, operation } = req.body; // key is the S3 object key (file identifier) const url = await s3UploadService.generatePresignedUrl(key, operation); res.status(200).json({ url }); } catch (error) { next(error); } }; export const initializeMultipartUpload = async (req, res, next) => { try { const { key } = req.body; const uploadId = await s3UploadService.createMultipartUpload(key); res.status(200).json({ uploadId }); } catch (error) { next(error); } }; export const generateUploadPartUrls = async (req, res, next) => { try { const { key, uploadId, parts } = req.body; // parts is the number of parts const urls = await Promise.all( [...Array(parts).keys()].map(async (index) => { const partNumber = index + 1; const url = await s3UploadService.generateUploadPartUrl(key, uploadId, partNumber); return { partNumber, url }; }) ); res.status(200).json({ urls }); } catch (error) { next(error); } }; export const completeMultipartUpload = async (req, res, next) => { try { const { key, uploadId, parts } = req.body; // parts is an array of { ETag, PartNumber } const result = await s3UploadService.completeMultipartUpload(key, uploadId, parts); res.status(200).json({ result }); } catch (error) { next(error); } }; export const abortMultipartUpload = async (req, res, next) => { try { const { key, uploadId } = req.body; await s3UploadService.abortMultipartUpload(key, uploadId); res.status(200).json({ message: 'Upload aborted' }); } catch (error) { next(error); } };
Sediakan laluan untuk titik akhir ini dalam apl Express anda atau mana-mana rangka kerja yang anda gunakan.
Halaman hadapan akan mengendalikan pemilihan fail, memutuskan sama ada untuk melakukan muat naik satu bahagian atau berbilang bahagian berdasarkan saiz fail dan mengurus proses muat naik.
Secara umum, AWS mengesyorkan "apabila saiz objek anda mencapai 100 MB, anda harus mempertimbangkan untuk menggunakan muat naik berbilang bahagian dan bukannya memuat naik objek dalam satu operasi." Sumber
// services/S3UploadService.js import { S3Client, CreateMultipartUploadCommand, CompleteMultipartUploadCommand, UploadPartCommand, AbortMultipartUploadCommand, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, } from '@aws-sdk/client-s3'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; // Import credential providers import { fromIni, fromInstanceMetadata, fromEnv, fromProcess, } from '@aws-sdk/credential-providers'; export class S3UploadService { constructor() { this.s3BucketName = process.env.S3_BUCKET_NAME; this.s3Region = process.env.S3_REGION; this.s3Client = new S3Client({ region: this.s3Region, credentials: this.getS3ClientCredentials(), }); } // Method to generate AWS credentials securely getS3ClientCredentials() { if (process.env.NODE_ENV === 'development') { // In development, use credentials from environment variables return fromEnv(); } else { // In production, use credentials from EC2 instance metadata or another secure method return fromInstanceMetadata(); } } // Generate a presigned URL for single-part upload (PUT), download (GET), or deletion (DELETE) async generatePresignedUrl(key, operation) { let command; switch (operation) { case 'PUT': command = new PutObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; case 'GET': command = new GetObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; case 'DELETE': command = new DeleteObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; default: throw new Error(`Invalid operation "${operation}"`); } // Generate presigned URL return await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); // Expires in 1 hour } // Methods for multipart upload async createMultipartUpload(key) { const command = new CreateMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, }); const response = await this.s3Client.send(command); return response.UploadId; } async generateUploadPartUrl(key, uploadId, partNumber) { const command = new UploadPartCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, PartNumber: partNumber, }); return await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); } async completeMultipartUpload(key, uploadId, parts) { const command = new CompleteMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, MultipartUpload: { Parts: parts }, }); return await this.s3Client.send(command); } async abortMultipartUpload(key, uploadId) { const command = new AbortMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, }); return await this.s3Client.send(command); } }
// controllers/S3UploadController.js import { S3UploadService } from '../services/S3UploadService'; const s3UploadService = new S3UploadService(); export const generatePresignedUrl = async (req, res, next) => { try { const { key, operation } = req.body; // key is the S3 object key (file identifier) const url = await s3UploadService.generatePresignedUrl(key, operation); res.status(200).json({ url }); } catch (error) { next(error); } }; export const initializeMultipartUpload = async (req, res, next) => { try { const { key } = req.body; const uploadId = await s3UploadService.createMultipartUpload(key); res.status(200).json({ uploadId }); } catch (error) { next(error); } }; export const generateUploadPartUrls = async (req, res, next) => { try { const { key, uploadId, parts } = req.body; // parts is the number of parts const urls = await Promise.all( [...Array(parts).keys()].map(async (index) => { const partNumber = index + 1; const url = await s3UploadService.generateUploadPartUrl(key, uploadId, partNumber); return { partNumber, url }; }) ); res.status(200).json({ urls }); } catch (error) { next(error); } }; export const completeMultipartUpload = async (req, res, next) => { try { const { key, uploadId, parts } = req.body; // parts is an array of { ETag, PartNumber } const result = await s3UploadService.completeMultipartUpload(key, uploadId, parts); res.status(200).json({ result }); } catch (error) { next(error); } }; export const abortMultipartUpload = async (req, res, next) => { try { const { key, uploadId } = req.body; await s3UploadService.abortMultipartUpload(key, uploadId); res.status(200).json({ message: 'Upload aborted' }); } catch (error) { next(error); } };
Walaupun AWS S3 menyokong objek bersaiz sehingga 5 TiB (terabait), memuat naik fail besar itu terus daripada penyemak imbas adalah tidak praktikal dan selalunya mustahil disebabkan oleh pengehadan penyemak imbas dan kekangan sumber pihak pelanggan. Penyemak imbas boleh ranap atau tidak bertindak balas apabila mengendalikan fail yang sangat besar, terutamanya jika ia perlu diproses dalam ingatan.
Memuat naik fail besar meningkatkan risiko gangguan atau kegagalan rangkaian semasa proses muat naik. Melaksanakan strategi cuba semula yang mantap adalah penting untuk meningkatkan pengalaman pengguna dan memastikan muat naik yang berjaya.
Muat naik berbilang bahagian yang tidak lengkap boleh terkumpul dalam baldi S3 anda, memakan ruang storan dan berkemungkinan menimbulkan kos.
Contoh Konfigurasi Peraturan Kitar Hayat:
// services/S3UploadService.js import { S3Client, CreateMultipartUploadCommand, CompleteMultipartUploadCommand, UploadPartCommand, AbortMultipartUploadCommand, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, } from '@aws-sdk/client-s3'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; // Import credential providers import { fromIni, fromInstanceMetadata, fromEnv, fromProcess, } from '@aws-sdk/credential-providers'; export class S3UploadService { constructor() { this.s3BucketName = process.env.S3_BUCKET_NAME; this.s3Region = process.env.S3_REGION; this.s3Client = new S3Client({ region: this.s3Region, credentials: this.getS3ClientCredentials(), }); } // Method to generate AWS credentials securely getS3ClientCredentials() { if (process.env.NODE_ENV === 'development') { // In development, use credentials from environment variables return fromEnv(); } else { // In production, use credentials from EC2 instance metadata or another secure method return fromInstanceMetadata(); } } // Generate a presigned URL for single-part upload (PUT), download (GET), or deletion (DELETE) async generatePresignedUrl(key, operation) { let command; switch (operation) { case 'PUT': command = new PutObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; case 'GET': command = new GetObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; case 'DELETE': command = new DeleteObjectCommand({ Bucket: this.s3BucketName, Key: key, }); break; default: throw new Error(`Invalid operation "${operation}"`); } // Generate presigned URL return await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); // Expires in 1 hour } // Methods for multipart upload async createMultipartUpload(key) { const command = new CreateMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, }); const response = await this.s3Client.send(command); return response.UploadId; } async generateUploadPartUrl(key, uploadId, partNumber) { const command = new UploadPartCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, PartNumber: partNumber, }); return await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); } async completeMultipartUpload(key, uploadId, parts) { const command = new CompleteMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, MultipartUpload: { Parts: parts }, }); return await this.s3Client.send(command); } async abortMultipartUpload(key, uploadId) { const command = new AbortMultipartUploadCommand({ Bucket: this.s3BucketName, Key: key, UploadId: uploadId, }); return await this.s3Client.send(command); } }
Memuat naik fail besar boleh memerlukan sumber dan boleh menyebabkan urutan utama penyemak imbas menjadi tidak bertindak balas, membawa kepada pengalaman pengguna yang buruk.
Apabila melaksanakan muat naik berbilang bahagian sisi klien, keserasian penyemak imbas sememangnya menjadi kebimbangan. Penyemak imbas yang berbeza mungkin mempunyai tahap sokongan yang berbeza-beza untuk API dan ciri yang diperlukan untuk mengendalikan muat naik fail yang besar, seperti *API Fail, Penghirisan Blob, Pekerja Web dan pengendalian permintaan rangkaian* . Menavigasi perbezaan ini dengan jayanya adalah penting untuk memastikan pengalaman pengguna yang konsisten dan boleh dipercayai merentas semua penyemak imbas yang disokong.
Dengan melaksanakan muat naik sebelah klien dengan URL yang ditetapkan dan muat naik berbilang bahagian, anda boleh mengendalikan muat naik fail dalam sebarang saiz terus ke S3 dengan cekap, mengurangkan beban pelayan dan meningkatkan prestasi. Ingatlah untuk mengekalkan keselamatan di barisan hadapan dengan mengurus bukti kelayakan AWS dengan selamat dan mengehadkan kebenaran dan jangka hayat URL yang ditetapkan.
Panduan ini menyediakan pendekatan langkah demi langkah untuk menyediakan sistem muat naik fail yang selamat dan berskala menggunakan AWS S3, AWS SDK untuk JavaScript dan URL yang ditetapkan. Dengan contoh kod dan amalan terbaik yang disediakan, anda sedang dalam perjalanan untuk meningkatkan keupayaan muat naik fail aplikasi anda.
Atas ialah kandungan terperinci Mengoptimumkan Muat Naik Fail Besar: Muat Naik Berbilang Bahagian Sebelah Pelanggan yang Selamat ke AWS S3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!