Question

J'utilise Azure Storage pour servir les blobs de fichiers statiques, mais je voudrais ajouter une Cache-Control et Expires aux fichiers / blobs lorsque servi à réduire les coûts de bande passante.

Application comme CloudXplorer et de Cerebrata cloud Storage studio options de donner à des propriétés de métadonnées ensemble sur les conteneurs et blobs mais se fâcher lorsque vous essayez d'ajouter Cache-Control.

Quelqu'un sait s'il est possible de définir ces en-têtes des fichiers?

Était-ce utile?

La solution

Je devais exécuter un traitement par lots sur environ 600k blobs et trouvé 2 choses qui ont vraiment aidé:

  1. L'exécution de l'opération d'un rôle de travailleur dans le même centre de données. La vitesse entre les services Azure est grande aussi longtemps qu'ils sont dans le même groupe d'affinité. De plus, il n'y a pas de frais de transfert de données.
  2. L'exécution de l'opération en parallèle. La bibliothèque parallèle de tâches (TPL) en .net v4 fait vraiment facilement. Voici le code pour définir l'en-tête de contrôle du cache pour chaque blob dans un récipient en parallèle:

    // get the info for every blob in the container
    var blobInfos = cloudBlobContainer.ListBlobs(
        new BlobRequestOptions() { UseFlatBlobListing = true });
    Parallel.ForEach(blobInfos, (blobInfo) =>
    {
        // get the blob properties
        CloudBlob blob = container.GetBlobReference(blobInfo.Uri.ToString());
        blob.FetchAttributes();
    
        // set cache-control header if necessary
        if (blob.Properties.CacheControl != YOUR_CACHE_CONTROL_HEADER)
        {
            blob.Properties.CacheControl = YOUR_CACHE_CONTROL_HEADER;
            blob.SetProperties();
        }
    });
    

Autres conseils

Voici une version mise à jour de la réponse de Joel Fillmore:

Au lieu de créer un site Web et en utilisant un WorkerRole, Azure a maintenant la possibilité d'exécuter « WebJobs ». Vous pouvez exécuter un exécutable sur demande sur un site au même centre de données où votre compte de stockage est situé aux en-têtes de cache ensemble ou tout autre champ d'en-tête.

  1. Créer une touche loin, site temporaire dans le même centre de données que votre compte de stockage. Ne vous préoccupez pas des groupes d'affinité; créer un site ASP.NET vide ou tout autre site simple. Le contenu est sans importance.
  2. Créer un programme de console en utilisant le code ci-dessous qui fonctionne avec les mises à jour Azure API de stockage. Compiler pour la libération, puis l'exécutable zip et toutes les DLL nécessaires dans un fichier .zip.
  3. Créer un WebJob et télécharger le fichier .zip de l'étape 2. entrer image description ici
  4. Lancez le WebJob. Tout sur la console est disponible à la vue dans le fichier journal créé et accessible à partir de la page de contrôle de WebJob.
  5. Notez la méthode UpdateAzureServiceVersion. Apparemment, par défaut, le stockage Azure mal formaté ETags sert de sorte que vous pouvez exécuter ce code une fois, pour plus de détails voir: cette

Le code ci-dessous exécute une tâche distincte pour chaque conteneur, et je reçois environ 70 têtes mises à jour par seconde par conteneur. Aucun frais de sortie.

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

namespace AzureHeaders
{
    class Program
    {
        static StorageCredentials storageCredentials =
            new StorageCredentials("azureaccountname", @"azzureaccountkey");
        private static string newCacheSettings = "public, max-age=7776000"; // 3 months
        private static string[] containersToProcess = { "container1", "container2" };

        static void Main(string[] args)
        {
            var account = new CloudStorageAccount(
                storageCredentials,
                false /* useHttps */);

            CloudBlobClient blobClient = account.CreateCloudBlobClient();

            var tasks = new List<Task>();
            foreach (var container in blobClient.ListContainers())
            {
                if (containersToProcess.Contains(container.Name))
                {
                    var c = container;
                    tasks.Add(Task.Run(() => FixHeaders(c)));
                }
            }
            Task.WaitAll(tasks.ToArray());
        }

        private static async Task FixHeaders(CloudBlobContainer cloudBlobContainer)
        {
            int totalCount = 0, updateCount = 0, errorCount = 0;

            Console.WriteLine("Starting container: " + cloudBlobContainer.Name);
            IEnumerable<IListBlobItem> blobInfos = cloudBlobContainer.ListBlobs(useFlatBlobListing: true);

            foreach (var blobInfo in blobInfos)
            {
                try
                {
                    CloudBlockBlob blockBlob = (CloudBlockBlob)blobInfo;
                    var blob = await cloudBlobContainer.GetBlobReferenceFromServerAsync(blockBlob.Name);
                    blob.FetchAttributes();

                    // set cache-control header if necessary
                    if (blob.Properties.CacheControl != newCacheSettings)
                    {
                        blob.Properties.CacheControl = newCacheSettings;
                        blob.SetProperties();
                        updateCount++;
                    }
                }
                catch (Exception ex)
                {
                    // Console.WriteLine(ex.Message);
                    errorCount++;
                }
                totalCount++;
            }
            Console.WriteLine("Finished container: " + cloudBlobContainer.Name + 
                ", TotalCount = " + totalCount + 
                ", Updated = " + updateCount + 
                ", Errors = " + errorCount);
        }

        // http://geekswithblogs.net/EltonStoneman/archive/2014/10/09/configure-azure-storage-to-return-proper-response-headers-for-blob.aspx
        private static void UpdateAzureServiceVersion(CloudBlobClient blobClient)
        {
            var props = blobClient.GetServiceProperties();
            props.DefaultServiceVersion = "2014-02-14";
            blobClient.SetServiceProperties(props);
        }
    }
}

La dernière version de Cerebrata Cloud Storage studio , v2011.04.23.00 , la mise en cache des supports de contrôle sur les objets blob individuels. Faites un clic droit sur l'objet blob, choisissez « Afficher / Modifier Blob Propriétés » puis définissez la valeur de l'attribut Cache-Control. (Par exemple public, max-age=2592000).

Si vous cochez la entêtes HTTP de l'objet blob à l'aide curl, vous verrez l'en-tête de contrôle du cache retourné avec la valeur que vous définissez.

Parfois, la réponse la plus simple est la meilleure. Si vous voulez juste gérer une petite quantité de blobs, vous pouvez utiliser Azure gestion pour modifier les en-têtes / métadonnées pour vos blobs.

  1. Cliquez sur Stockage , puis cliquez sur le nom du compte de stockage.
  2. Cliquez sur Conteneurs onglet, puis cliquez sur un conteneur.
  3. Cliquez sur un blob, puis cliquez sur Modifier en bas de l'écran.

Dans cette fenêtre d'édition, vous pouvez personnaliser le Cache Control , Contenu Encoding , Langue du contenu , et plus encore.

Note: vous ne pouvez pas actuellement modifier ces données de la

Il est peut-être trop tard pour répondre, mais récemment je voulais faire la même chose de manière différente, où j'ai liste des images et nécessaires à l'application en utilisant un script PowerShell (bien sûr avec l'aide assemblage de stockage Azure) quelqu'un Hope trouvera ce utile à l'avenir.

L'explication complète donnée dans Set cache-control blob Azure en utilisant le script Powershell

Add-Type -Path "C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\v2.3\ref\Microsoft.WindowsAzure.StorageClient.dll"

$accountName = "[azureaccountname]"
$accountKey = "[azureaccountkey]"
$blobContainerName = "images"

$storageCredentials = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey -ArgumentList $accountName,$accountKey
$storageAccount = New-Object Microsoft.WindowsAzure.CloudStorageAccount -ArgumentList $storageCredentials,$true
#$blobClient = $storageAccount.CreateCloudBlobClient()
$blobClient =  [Microsoft.WindowsAzure.StorageClient.CloudStorageAccountStorageClientExtensions]::CreateCloudBlobClient($storageAccount)

$cacheControlValue = "public, max-age=604800"

echo "Setting cache control: $cacheControlValue"

Get-Content "imagelist.txt" | foreach {     
    $blobName = "$blobContainerName/$_".Trim()
    echo $blobName
    $blob = $blobClient.GetBlobReference($blobName)
    $blob.Properties.CacheControl = $cacheControlValue
    $blob.SetProperties()
}

Définir les propriétés cache de contrôle blob de stockage par le script PowerShell

https://gallery.technet.microsoft.com/ How-to-set-stockage blob-4774aca5

#creat CloudBlobClient 
Add-Type -Path "C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\v2.3\ref\Microsoft.WindowsAzure.StorageClient.dll" 
$storageCredentials = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey -ArgumentList $StorageName,$StorageKey 
$blobClient =   New-Object Microsoft.WindowsAzure.StorageClient.CloudBlobClient($BlobUri,$storageCredentials) 
#set Properties and Metadata 
$cacheControlValue = "public, max-age=60480" 
foreach ($blob in $blobs) 
{ 
  #set Metadata 
  $blobRef = $blobClient.GetBlobReference($blob.Name) 
  $blobRef.Metadata.Add("abcd","abcd") 
  $blobRef.SetMetadata() 

  #set Properties 
  $blobRef.Properties.CacheControl = $cacheControlValue 
  $blobRef.SetProperties() 
}

Voici une version mise à jour de la réponse de Joel Fillmore consommation WindowsAzure.Storage v9.3.3. Notez que ListBlobsSegmentedAsync retourne une taille de page de 5000 qui est la raison pour laquelle le BlobContinuationToken est utilisé.

    public async Task BackfillCacheControlAsync()
    {
        var container = await GetCloudBlobContainerAsync();
        BlobContinuationToken continuationToken = null;

        do
        {
            var blobInfos = await container.ListBlobsSegmentedAsync(string.Empty, true, BlobListingDetails.None, null, continuationToken, null, null);
            continuationToken = blobInfos.ContinuationToken;
            foreach (var blobInfo in blobInfos.Results)
            {
                var blockBlob = (CloudBlockBlob)blobInfo;
                var blob = await container.GetBlobReferenceFromServerAsync(blockBlob.Name);
                if (blob.Properties.CacheControl != "public, max-age=31536000")
                {
                    blob.Properties.CacheControl = "public, max-age=31536000";
                    await blob.SetPropertiesAsync();
                }
            }               
        }
        while (continuationToken != null);
    }

    private async Task<CloudBlobContainer> GetCloudBlobContainerAsync()
    {
        var storageAccount = CloudStorageAccount.Parse(_appSettings.AzureStorageConnectionString);
        var blobClient = storageAccount.CreateCloudBlobClient();
        var container = blobClient.GetContainerReference("uploads");
        return container;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top