Stockage Blob non structuré (création d’applications cloud Real-World avec Azure)

par Rick Anderson, Tom Dykstra

Télécharger corriger le projet ou télécharger le livre électronique

Le livre électronique Building Real World Cloud Apps with Azure est basé sur une présentation développée par Scott Guthrie. Il explique 13 modèles et pratiques qui peuvent vous aider à développer des applications web pour le cloud. Pour plus d’informations sur le livre électronique, consultez le premier chapitre.

Dans le chapitre précédent, nous avons examiné les schémas de partitionnement et expliqué comment l’application Fix It stocke des images dans le service Blob Stockage Azure et d’autres données de tâche dans Azure SQL Database. Dans ce chapitre, nous allons plus en détail sur le service Blob et montrons comment il est implémenté dans le code du projet Corriger.

Présentation du stockage d'objets blob

Le service Stockage Blob Azure permet de stocker des fichiers dans le cloud. Le service Blob présente plusieurs avantages par rapport au stockage de fichiers dans un système de fichiers réseau local :

  • Il est hautement évolutif. Un seul compte de stockage peut stocker des centaines de téraoctets, et vous pouvez avoir plusieurs comptes de stockage. Certains des plus grands clients Azure stockent des centaines de pétaoctets. Microsoft SkyDrive utilise le stockage d’objets blob.
  • C’est durable. Chaque fichier que vous stockez dans le service Blob est automatiquement sauvegardé.
  • Il offre une haute disponibilité. Le contrat SLA pour le stockage promet une disponibilité de 99,9 % ou 99,99 %, selon l’option de géo-redondance que vous choisissez.
  • Il s’agit d’une fonctionnalité PaaS (platform-as-a-service) d’Azure, ce qui signifie que vous stockez et récupérez simplement des fichiers, en payant uniquement la quantité réelle de stockage que vous utilisez, et Azure prend automatiquement en charge la configuration et la gestion de toutes les machines virtuelles et lecteurs de disque requis pour le service.
  • Vous pouvez accéder au service Blob à l’aide d’une API REST ou d’une API de langage de programmation. Les sdk sont disponibles pour .NET, Java, Ruby et d’autres.
  • Lorsque vous stockez un fichier dans le service Blob, vous pouvez facilement le rendre accessible publiquement sur Internet.
  • Vous pouvez sécuriser les fichiers dans le service Blob afin qu’ils ne soient accessibles que par les utilisateurs autorisés, ou vous pouvez fournir des jetons d’accès temporaires qui les rendent accessibles à quelqu’un uniquement pendant une période limitée.

Chaque fois que vous créez une application pour Azure et que vous souhaitez stocker un grand nombre de données qui, dans un environnement local, sont contenues dans des fichiers, tels que des images, des vidéos, des fichiers PDF, des feuilles de calcul, etc. -- considérez le service Blob.

Création d’un compte de stockage

Pour commencer à utiliser le service Blob, vous créez un compte de stockage dans Azure. Dans le portail, cliquez surCréation rapidenouveau -- stockage -- Data Services -- , puis entrez une URL et un emplacement de centre de données. L’emplacement du centre de données doit être identique à celui de votre application web.

Créer un accès de stockage

Vous choisissez la région principale dans laquelle vous souhaitez stocker le contenu. Si vous choisissez l’option de géoréplication , Azure crée des réplicas de toutes vos données dans un autre centre de données dans une autre partie du pays ou de la région. Par exemple, si vous choisissez le centre de données USA Ouest, lorsque vous stockez un fichier, il va au centre de données USA Ouest, mais en arrière-plan Azure le copie également dans l’un des autres centres de données américains. Si un sinistre se produit dans une partie du pays ou de la région, vos données sont toujours en sécurité.

Azure ne répliquera pas les données au-delà des limites géopolitiques : si votre emplacement principal se trouve aux États-Unis, vos fichiers ne sont répliqués que dans une autre région des États-Unis ; si votre emplacement principal est l’Australie, vos fichiers sont uniquement répliqués dans un autre centre de données en Australie.

Bien sûr, vous pouvez également créer un compte de stockage en exécutant des commandes à partir d’un script, comme nous l’avons vu précédemment. Voici une commande Windows PowerShell pour créer un compte de stockage :

# Create a new storage account
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose

Une fois que vous disposez d’un compte de stockage, vous pouvez immédiatement commencer à stocker des fichiers dans le service Blob.

Utilisation du stockage Blob dans l’application Corriger le problème

L’application Corriger vous permet de charger des photos.

Créer une tâche de correction

Lorsque vous cliquez sur Créer le CorrectifIt, l’application charge le fichier image spécifié et le stocke dans le service Blob.

Configurer le conteneur d’objets blob

Pour stocker un fichier dans le service Blob, vous avez besoin d’un conteneur dans lequel le stocker. Un conteneur de service Blob correspond à un dossier de système de fichiers. Les scripts de création d’environnement que nous avons examinés dans le chapitre Automatiser tout créent le compte de stockage, mais ils ne créent pas de conteneur. L’objectif de la CreateAndConfigure méthode de la PhotoService classe est donc de créer un conteneur s’il n’existe pas déjà. Cette méthode est appelée à partir de la Application_Start méthode dans Global.asax.

public async void CreateAndConfigureAsync()
{
    try
    {
        CloudStorageAccount storageAccount = StorageUtils.StorageAccount;

        // Create a blob client and retrieve reference to images container
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("images");

        // Create the "images" container if it doesn't already exist.
        if (await container.CreateIfNotExistsAsync())
        {
            // Enable public access on the newly created "images" container
            await container.SetPermissionsAsync(
                new BlobContainerPermissions
                {
                    PublicAccess =
                        BlobContainerPublicAccessType.Blob
                });

            log.Information("Successfully created Blob Storage Images Container and made it public");
        }
    }
    catch (Exception ex)
    {
        log.Error(ex, "Failure to Create or Configure images container in Blob Storage Service");
    }
}

Le nom du compte de stockage et la clé d’accès sont stockés dans la appSettings collection du fichier Web.config , et le code de la StorageUtils.StorageAccount méthode utilise ces valeurs pour créer une chaîne de connexion et établir une connexion :

string account = CloudConfigurationManager.GetSetting("StorageAccountName");
string key = CloudConfigurationManager.GetSetting("StorageAccountAccessKey");
string connectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", account, key);
return CloudStorageAccount.Parse(connectionString);

La CreateAndConfigureAsync méthode crée ensuite un objet qui représente le service Blob et un objet qui représente un conteneur (dossier) nommé « images » dans le service Blob :

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");

Si un conteneur nommé « images » n’existe pas encore ,ce qui sera vrai la première fois que vous exécutez l’application sur un nouveau compte de stockage, le code crée le conteneur et définit les autorisations pour le rendre public. (Par défaut, les nouveaux conteneurs d’objets blob sont privés et sont accessibles uniquement aux utilisateurs qui ont l’autorisation d’accéder à votre compte de stockage.)

if (await container.CreateIfNotExistsAsync())
{
    // Enable public access on the newly created "images" container
    await container.SetPermissionsAsync(
        new BlobContainerPermissions
        {
            PublicAccess =
                BlobContainerPublicAccessType.Blob
        });

    log.Information("Successfully created Blob Storage Images Container and made it public");
}

Stocker la photo chargée dans le stockage Blob

Pour charger et enregistrer le fichier image, l’application utilise une IPhotoService interface et une implémentation de l’interface dans la PhotoService classe . Le fichier PhotoService.cs contient tout le code de l’application Corriger qui communique avec le service Blob.

La méthode de contrôleur MVC suivante est appelée lorsque l’utilisateur clique sur Créer le FixIt. Dans ce code, photoService fait référence à un instance de la PhotoService classe et fixittask à un instance de la FixItTask classe d’entité qui stocke les données d’une nouvelle tâche.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "FixItTaskId,CreatedBy,Owner,Title,Notes,PhotoUrl,IsDone")]FixItTask fixittask, HttpPostedFileBase photo)
{
    if (ModelState.IsValid)
    {
        fixittask.CreatedBy = User.Identity.Name;
        fixittask.PhotoUrl = await photoService.UploadPhotoAsync(photo);
        await fixItRepository.CreateAsync(fixittask);
        return RedirectToAction("Success");
    }

    return View(fixittask);
}

La UploadPhotoAsync méthode de la PhotoService classe stocke le fichier chargé dans le service Blob et retourne une URL qui pointe vers le nouvel objet blob.

public async Task<string> UploadPhotoAsync(HttpPostedFileBase photoToUpload)
{            
    if (photoToUpload == null || photoToUpload.ContentLength == 0)
    {
        return null;
    }

    string fullPath = null;
    Stopwatch timespan = Stopwatch.StartNew();

    try
    {
        CloudStorageAccount storageAccount = StorageUtils.StorageAccount;

        // Create the blob client and reference the container
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("images");

        // Create a unique name for the images we are about to upload
        string imageName = String.Format("task-photo-{0}{1}",
            Guid.NewGuid().ToString(),
            Path.GetExtension(photoToUpload.FileName));

        // Upload image to Blob Storage
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
        blockBlob.Properties.ContentType = photoToUpload.ContentType;
        await blockBlob.UploadFromStreamAsync(photoToUpload.InputStream);

        // Convert to be HTTP based URI (default storage path is HTTPS)
        var uriBuilder = new UriBuilder(blockBlob.Uri);
        uriBuilder.Scheme = "http";
        fullPath = uriBuilder.ToString();

        timespan.Stop();
        log.TraceApi("Blob Service", "PhotoService.UploadPhoto", timespan.Elapsed, "imagepath={0}", fullPath);
    }
    catch (Exception ex)
    {
        log.Error(ex, "Error upload photo blob to storage");
    }

    return fullPath;
}

Comme dans la CreateAndConfigure méthode, le code se connecte au compte de stockage et crée un objet qui représente le conteneur d’objets blob « images », sauf ici, il suppose que le conteneur existe déjà.

Ensuite, il crée un identificateur unique pour l’image sur le point d’être chargée, en concaténant une nouvelle valeur GUID avec l’extension de fichier :

string imageName = String.Format("task-photo-{0}{1}",
    Guid.NewGuid().ToString(),
    Path.GetExtension(photoToUpload.FileName));

Le code utilise ensuite l’objet conteneur d’objets blob et le nouvel identificateur unique pour créer un objet blob, définit un attribut sur cet objet indiquant le type de fichier qu’il est, puis utilise l’objet blob pour stocker le fichier dans le stockage blob.

CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
blockBlob.Properties.ContentType = photoToUpload.ContentType;
blockBlob.UploadFromStream(photoToUpload.InputStream);

Enfin, il obtient une URL qui fait référence à l’objet blob. Cette URL sera stockée dans la base de données et peut être utilisée dans les pages web Corriger pour afficher l’image chargée.

fullPath = String.Format("http://{0}{1}", blockBlob.Uri.DnsSafeHost, blockBlob.Uri.AbsolutePath);

Cette URL est stockée dans la base de données sous la forme d’une des colonnes de la table FixItTask.

public class FixItTask
{
    public int FixItTaskId  { get; set; }
    public string CreatedBy { get; set; }
    [Required]
    public string Owner     { get; set; }
    [Required]
    public string Title     { get; set; }
    public string Notes     { get; set; }
    public string PhotoUrl  { get; set; }
    public bool IsDone      { get; set; } 
}

Avec uniquement l’URL de la base de données et les images dans le stockage Blob, l’application Corriger conserve la base de données petite, évolutive et peu coûteuse, tandis que les images sont stockées là où le stockage est bon marché et permet de gérer des téraoctets ou des pétaoctets. Un compte de stockage peut stocker des centaines de téraoctets de photos corriger le problème, et vous ne payez que pour ce que vous utilisez. Ainsi, vous pouvez commencer à payer 9 centimes pour le premier gigaoctet, et ajouter d’autres images pour des centimes par gigaoctet supplémentaire.

Afficher le fichier chargé

L’application Corriger affiche le fichier image chargé lorsqu’elle affiche les détails d’une tâche.

Corriger les détails de la tâche avec photo

Pour afficher l’image, il suffit d’inclure la valeur dans le PhotoUrl code HTML envoyé au navigateur. Le serveur web et la base de données n’utilisent pas de cycles pour afficher l’image, ils ne servent que quelques octets à l’URL de l’image. Dans le code Razor suivant, Model fait référence à une instance de la classe d’entitéFixItTask.

<fieldset>
<legend>@Html.DisplayFor(model => model.Title)</legend>
<dl>
    <dt>Opened By</dt>
    <dd>@Html.DisplayFor(model => model.CreatedBy)</dd>
                <br />
    <dt>@Html.DisplayNameFor(model => model.Notes)</dt>
    <dd>@Html.DisplayFor(model => model.Notes)</dd>
                <br />
                @if(Model.PhotoUrl != null) {
        <dd><img src="@Model.PhotoUrl" title="@Model.Title" /></dd>
                }
</dl>
</fieldset>

Si vous examinez le code HTML de la page qui s’affiche, vous voyez que l’URL pointe directement vers l’image dans le stockage d’objets blob, comme suit :

<fieldset>
<legend>Brush the dog again</legend>
<dl>
    <dt>Opened By</dt>
    <dd>Tom</dd>
                <br />
    <dt>Notes</dt>
    <dd>Another dog brushing task</dd>
                <br />
    <dd>
<img src="http://storageaccountname.blob.core.windows.net/images/task-photo-312dd635-ba87-4542-8b15-767032c55f4e.jpg" 
           title="Brush the dog again" />
    </dd>
</dl>
</fieldset>

Résumé

Vous avez vu comment l’application Corriger stocke des images dans le service Blob et uniquement des URL d’image dans la base de données SQL. L’utilisation du service Blob conserve la base de données SQL beaucoup plus petite qu’elle ne le serait sinon, permet d’effectuer un scale-up jusqu’à un nombre presque illimité de tâches et peut être effectuée sans écrire beaucoup de code.

Vous pouvez avoir des centaines de téraoctets dans un compte de stockage, et le coût de stockage est beaucoup moins cher que SQL Database stockage, à partir d’environ 3 centimes par gigaoctet par mois, plus un petit frais de transaction. Et gardez à l’esprit que vous ne payez pas pour la capacité maximale, mais uniquement pour le montant que vous stockez réellement, de sorte que votre application est prête à être mise à l’échelle, mais vous ne payez pas pour toute cette capacité supplémentaire.

Dans le chapitre suivant , nous aborderons l’importance de rendre une application cloud capable de gérer correctement les défaillances.

Ressources

Pour plus d’informations, consultez les ressources suivantes :

  • Comment utiliser le service Stockage Blob Azure dans .NET. Documentation officielle sur le site MicrosoftAzure.com. Brève présentation du stockage d’objets blob suivie d’exemples de code montrant comment se connecter au stockage d’objets blob, créer des conteneurs, charger et télécharger des objets blob, etc.
  • FailSafe : création de Services cloud évolutifs et résilients. Série vidéo en neuf parties par Ulrich Homann, Marc Mercuri et Mark Simms. Présente des concepts de haut niveau et des principes architecturaux d’une manière très accessible et intéressante, avec des histoires tirées de l’expérience de l’équipe de conseil à la clientèle Microsoft (CAT) avec des clients réels. Pour une présentation du service stockage Azure et des objets blob, consultez l’épisode 5 à partir de 35:13.
  • Modèles et pratiques Microsoft - Conseils Azure. Consultez Modèle de clé valet.