Dans un article précédent, nous avons créé un service de téléchargement de fichiers utilisant Go avec le stockage local et Amazon S3 pour le stockage basé sur le cloud. Mais que se passe-t-il si vous devez gérer des fichiers volumineux : pensez à des fichiers vidéo de plusieurs gigaoctets ou à des ensembles de données ? ? C’est là que les choses peuvent devenir délicates. Vous ne voulez pas que votre serveur s'enlise ou manque de mémoire.
Dans cet article, nous explorerons comment gérer efficacement les téléchargements de fichiers volumineux en utilisant le streaming et le chunking avec AWS S3. De cette façon, même les fichiers les plus volumineux ne mettront pas votre application à genoux.
Voici ce que nous allons aborder :
Prêt à envoyer ces fichiers volumineux dans le cloud ? Allons-y ! ?️
Lorsque vous téléchargez des fichiers volumineux, la dernière chose que vous souhaitez est de charger un fichier entier en mémoire. Pour les fichiers plus petits, ce n’est pas grave, mais avec des fichiers plus volumineux, vous atteindrez rapidement les limites de la mémoire de votre serveur, notamment lors de la gestion de plusieurs téléchargements simultanés.
LeStreaming et chunking sont des techniques clés qui vous permettent de gérer efficacement ces gros fichiers.
Nous utiliserons le SDK AWS pour diffuser le fichier à partir de la demande de téléchargement de l'utilisateur directement dans S3, minimisant ainsi la quantité de mémoire dont nous avons besoin sur le serveur.
Au lieu de stocker l'intégralité du fichier en mémoire ou sur disque avant de le télécharger sur S3, nous pouvons utiliser des streams pour envoyer le fichier en temps réel. Modifions notre fileUploadHandler existant pour gérer plus efficacement les fichiers volumineux.
import ( "fmt" "io" "net/http" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) func fileUploadHandler(w http.ResponseWriter, r *http.Request) { // Limit the request size (e.g., 10GB max size) r.Body = http.MaxBytesReader(w, r.Body, 10<<30) // Parse the multipart form data err := r.ParseMultipartForm(10 << 20) if err != nil { http.Error(w, "File too large", http.StatusRequestEntityTooLarge) return } // Retrieve the file from the form file, handler, err := r.FormFile("file") if err != nil { http.Error(w, "Error retrieving file", http.StatusBadRequest) return } defer file.Close() // Set up AWS session sess, err := session.NewSession(&aws.Config{ Region: aws.String("us-west-1"), }) if err != nil { http.Error(w, "Error connecting to AWS", http.StatusInternalServerError) return } // Create the S3 client s3Client := s3.New(sess) // Stream the file directly to S3 _, err = s3Client.PutObject(&s3.PutObjectInput{ Bucket: aws.String("your-bucket-name"), Key: aws.String(handler.Filename), Body: file, // Stream the file directly from the request ACL: aws.String("public-read"), }) if err != nil { http.Error(w, "Error uploading file to S3", http.StatusInternalServerError) return } fmt.Fprintf(w, "File uploaded successfully to S3!") }
Dans cette approche, le fichier est diffusé directement de la requête vers S3, vous ne stockez donc pas l'intégralité du fichier en mémoire, ce qui est une bouée de sauvetage pour les fichiers volumineux !
Si vous souhaitez aller plus loin, vous pouvez diviser les fichiers en morceaux côté client et les télécharger en morceaux plus petits. Ceci est particulièrement utile pour gérer des connexions irrégulières ou des fichiers volumineux, où il serait pénible de redémarrer un téléchargement à partir de zéro.
Côté client, divisez le fichier en morceaux plus petits et téléchargez chacun séparément. Voici un exemple utilisant JavaScript :
import ( "fmt" "io" "net/http" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) func fileUploadHandler(w http.ResponseWriter, r *http.Request) { // Limit the request size (e.g., 10GB max size) r.Body = http.MaxBytesReader(w, r.Body, 10<<30) // Parse the multipart form data err := r.ParseMultipartForm(10 << 20) if err != nil { http.Error(w, "File too large", http.StatusRequestEntityTooLarge) return } // Retrieve the file from the form file, handler, err := r.FormFile("file") if err != nil { http.Error(w, "Error retrieving file", http.StatusBadRequest) return } defer file.Close() // Set up AWS session sess, err := session.NewSession(&aws.Config{ Region: aws.String("us-west-1"), }) if err != nil { http.Error(w, "Error connecting to AWS", http.StatusInternalServerError) return } // Create the S3 client s3Client := s3.New(sess) // Stream the file directly to S3 _, err = s3Client.PutObject(&s3.PutObjectInput{ Bucket: aws.String("your-bucket-name"), Key: aws.String(handler.Filename), Body: file, // Stream the file directly from the request ACL: aws.String("public-read"), }) if err != nil { http.Error(w, "Error uploading file to S3", http.StatusInternalServerError) return } fmt.Fprintf(w, "File uploaded successfully to S3!") }
Côté serveur, vous pouvez recevoir ces chunks et les ajouter au fichier stocké sur S3 :
async function uploadFileInChunks(file) { const chunkSize = 5 * 1024 * 1024; // 5MB per chunk const totalChunks = Math.ceil(file.size / chunkSize); for (let i = 0; i < totalChunks; i++) { const start = i * chunkSize; const end = Math.min(file.size, start + chunkSize); const chunk = file.slice(start, end); const formData = new FormData(); formData.append("chunk", chunk); formData.append("chunkIndex", i); formData.append("filename", file.name); await fetch("/upload-chunk", { method: "POST", body: formData, }); } }
Cette méthode vous permet de télécharger des morceaux d'un fichier indépendamment et de les fusionner dans le cloud. Il est parfait pour gérer des téléchargements très volumineux où la fiabilité est essentielle.
Tailles limites des requêtes : définissez toujours une taille de requête maximale raisonnable (MaxBytesReader) pour empêcher les utilisateurs de surcharger votre serveur.
Téléchargements multiparts pour S3 : AWS S3 prend en charge les téléchargements multiparts, ce qui est idéal pour les fichiers volumineux. Vous pouvez télécharger des parties en parallèle et même reprendre les téléchargements ayant échoué.
Téléchargements de fichiers sécurisés : assurez-vous de valider les types de fichiers et d'utiliser des connexions sécurisées (HTTPS) pour les téléchargements de fichiers. Nettoyez les noms de fichiers pour empêcher les attaques par traversée de répertoires.
Indicateurs de progression : si vous segmentez des fichiers, implémentez un indicateur de progression pour une meilleure expérience utilisateur, en particulier pour les fichiers volumineux.
La gestion des téléchargements de fichiers volumineux ne doit pas être un casse-tête. En utilisant des techniques de streaming et de segmentation avec Go et S3, vous pouvez gérer efficacement même les fichiers les plus volumineux sans surcharger la mémoire de votre serveur. Que vous créiez un service de stockage de fichiers, une plateforme vidéo ou une application multimédia, vous êtes désormais équipé pour gérer des téléchargements massifs comme un pro. ?
Avez-vous mis en œuvre le téléchargement de fichiers volumineux dans vos projets ? Déposez votre expérience ou vos conseils dans les commentaires et poursuivons la conversation ! ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!