Maison > développement back-end > Golang > le corps du texte

Gérer les téléchargements de fichiers volumineux en Go avec AWS SStream comme un pro

Linda Hamilton
Libérer: 2024-10-20 06:08:02
original
278 Les gens l'ont consulté

Handling Large File Uploads in Go with AWS SStream Like a Pro

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 :

  1. Pourquoi la gestion de fichiers volumineux nécessite une attention particulière.
  2. Diffusion de fichiers volumineux directement sur S3 avec une utilisation minimale de la mémoire.
  3. Découper les gros fichiers et les réassembler sur S3.
  4. Bonnes pratiques pour le téléchargement de fichiers volumineux dans un environnement de production.

Prêt à envoyer ces fichiers volumineux dans le cloud ? Allons-y ! ?️


Étape 1 : Pourquoi la gestion des fichiers volumineux est différente

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.

Le

Streaming et chunking sont des techniques clés qui vous permettent de gérer efficacement ces gros fichiers.

  • Streaming : téléchargez les fichiers sur S3 au fur et à mesure qu'ils sont reçus par le serveur, plutôt que de charger l'intégralité du fichier en mémoire.
  • Chunking : divisez les fichiers volumineux en parties plus petites (morceaux) et téléchargez chaque morceau individuellement. Ceci est particulièrement utile pour reprendre les téléchargements ayant échoué ou pour les téléchargements en parallèle.

Étape 2 : diffuser des fichiers volumineux directement sur S3

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.

Mise à jour du gestionnaire de téléchargement

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!")
}
Copier après la connexion
Copier après la connexion

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 !


Étape 3 : regrouper 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.

Exemple de regroupement côté client

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!")
}
Copier après la connexion
Copier après la connexion

Gestion des fragments côté serveur

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,
    });
  }
}
Copier après la connexion

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.


Étape 4 : Meilleures pratiques pour les téléchargements de fichiers volumineux

  1. 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.

  2. 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é.

  3. 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.

  4. 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.


Conclusion

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!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!