Domanda

Sto utilizzando Azure per servire fino chiazze di file statici, ma mi piacerebbe aggiungere un Cache-Control e scade intestazione per i file / blob quando servito fino a ridurre i costi di banda.

CloudXplorer e di Cerebrata cloud Storage studio opzioni danno per impostare le proprietà dei metadati su contenitori e macchie, ma si arrabbiano quando si cerca di aggiungere cache-Control.

Qualcuno sa se è possibile impostare queste intestazioni per i file?

È stato utile?

Soluzione

ho dovuto eseguire un processo batch su circa 600k blob e ho trovato 2 cose che davvero aiutato:

  1. L'esecuzione dell'operazione da un ruolo dei lavoratori nella stessa data center. La velocità tra i servizi Azure è grande fintanto che sono nello stesso gruppo di affinità. Inoltre non ci sono costi di trasferimento dei dati.
  2. L'esecuzione del funzionamento in parallelo. La Task Parallel Library (TPL) in .net v4 rende il tutto veramente facile. Ecco il codice per impostare l'intestazione cache-control per ogni blob in un contenitore in parallelo:

    // 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();
        }
    });
    

Altri suggerimenti

Ecco una versione aggiornata della risposta di Joel Fillmore:

Invece di creare un sito web e l'utilizzo di un WorkerRole, Azure ha ora la possibilità di eseguire "WebJobs". È possibile eseguire qualsiasi file eseguibile su richiesta su un sito web allo stesso data center in cui il vostro account di archiviazione si trova alle intestazioni di cache set o qualsiasi altro campo di intestazione.

  1. Crea una rimessa di distanza, il sito temporaneo nella stessa data center il tuo account di archiviazione. Non preoccupatevi di gruppi di affinità; creare un sito ASP.NET vuoto o qualsiasi altro sito semplice. Il contenuto non è importante.
  2. Crea un programma di console usando il codice seguente, che funziona con le API di archiviazione Azure aggiornati. Compilarlo per il rilascio, e quindi comprimere il file eseguibile e tutte le DLL necessarie in un file .zip.
  3. Crea una WebJob e caricare il file .zip dal passaggio # 2. entrare descrizione dell'immagine qui
  4. Eseguire il WebJob. Tutto scritto al console è disponibile per la visualizzazione nel file di registro creato e accessibile dalla pagina di controllo WebJob.
  5. Si noti il ??metodo UpdateAzureServiceVersion. A quanto pare, per impostazione predefinita, lo stoccaggio Azure serve impropriamente formattato ETags così si potrebbe desiderare di eseguire questo codice, una volta, per i dettagli si veda: questo

Il codice di seguito viene eseguito un compito separato per ogni contenitore, e sto ottenendo circa 70 intestazioni aggiornati al secondo per ogni contenitore. Nessuna accusa di uscita.

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);
        }
    }
}

L'ultima versione di Cerebrata Cloud Storage Studio , v2011.04.23.00 , supporti impostazione cache-control su singoli oggetti BLOB. Fare clic destro sull'oggetto blob, scegliere "Visualizza / Modifica Blob Proprietà", quindi impostare il valore per l'attributo Cache-Control. (Ad esempio public, max-age=2592000).

Se si seleziona la intestazioni HTTP dell'oggetto blob utilizzando curl, vedrete l'intestazione cache-control tornato con il valore impostato.

A volte, la risposta più semplice è il migliore. Se si desidera solo per gestire una piccola quantità di macchie, è possibile utilizzare Azure gestione per cambiare l'intestazioni / metadati per il tuo blob.

  1. Fare clic su archiviazione , quindi fare clic sul nome account di archiviazione.
  2. Fare clic sul Container , quindi fare clic su un contenitore.
  3. Fare clic su un blob, quindi fare clic su Modifica nella parte inferiore dello schermo.

In questa finestra di modifica, è possibile personalizzare il Controllo Cache , Content Encoding , Contenuti lingua , e altro ancora.

Nota: non è possibile attualmente modifica di questi dati dal Azure Portale

Questo potrebbe essere troppo tardi per la risposta, ma di recente ho voluto fare lo stesso in modo diverso, dove ho elenco di immagini e aveva bisogno di applicare utilizzando lo script PowerShell (ovviamente con l'aiuto di archiviazione Azure montaggio) La speranza qualcuno troverà questo utile in futuro.

spiegazione completa dato in Set Azure blob cache-controllo utilizzando powershell sceneggiatura

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()
}

Imposta archiviazione BLOB proprietà della cache-control lo script PowerShell

https://gallery.technet.microsoft.com/ how-to-set-storage-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() 
}

Ecco una versione aggiornata della risposta di Joel Fillmore consumando WindowsAzure.Storage v9.3.3. Si noti che ListBlobsSegmentedAsync restituisce una dimensione di pagina di 5.000, che è il motivo per cui viene utilizzato il BlobContinuationToken.

    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;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top