Pregunta

Estoy usando Azure Storage para servir gotas de archivo estático pero me gustaría añadir un Cache-Control y la cabecera Expira a los archivos / manchas cuando se sirve a reducir los costos de ancho de banda.

aplicación como CloudXplorer y de Cerebrata Cloud Storage Studio opciones dan para establecer las propiedades de metadatos de los contenedores y manchas, pero se molestan cuando se trata de añadir Cache-control.

conozco a nadie si es posible establecer estas cabeceras de los archivos?

¿Fue útil?

Solución

que tenía que ejecutar un trabajo por lotes en unos 600k manchas y encontré 2 cosas que realmente ayudaron:

  1. Ejecución de la operación de un rol de trabajo en el mismo centro de datos. La velocidad entre los servicios de Azure es grande, siempre y cuando estén en el mismo grupo de afinidad. Además no hay costes de transferencia de datos.
  2. Ejecución de la operación en paralelo. La tarea paralela Biblioteca (TPL) en .NET v4 lo hace muy fácil. Aquí está el código para establecer la cabecera de control de caché para cada blob en un recipiente en paralelo:

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

Otros consejos

Aquí está una versión actualizada de la respuesta de Joel Fillmore:

En lugar de crear un sitio web y el uso de un WorkerRole, Azure ahora tiene la capacidad de ejecutar "WebJobs". Puede ejecutar cualquier archivo ejecutable de la demanda en un sitio web en el mismo centro de datos donde se encuentra su cuenta de almacenamiento en caché de las cabeceras de ajuste o cualquier otro campo de la cabecera.

  1. Crear una de usar y tirar, página web temporal en el mismo centro de datos como su cuenta de almacenamiento. No se preocupe por grupos de afinidad; crear un sitio ASP.NET vacío o cualquier otro sitio simple. El contenido no es importante.
  2. Crear un programa de consola con el siguiente código que funciona con la API de almacenamiento de Azure actualizados. Compilarlo para el lanzamiento, y luego comprimir el ejecutable y todas las DLL necesarias en un archivo .zip.
  3. Crea un WebJob y cargar el archivo .zip desde el paso # 2. introducir descripción de la imagen aquí
  4. Ejecutar el WebJob. Todo lo escrito en la consola está disponible para ver en el archivo de registro creado y accesible desde la página de control WebJob.
  5. Tenga en cuenta el método UpdateAzureServiceVersion. Al parecer, por defecto, el almacenamiento Azure sirve inadecuadamente ETags formateado por lo que puede que desee ejecutar este código una vez, para más detalles véase: esta

El siguiente código se ejecuta una tarea independiente para cada contenedor, y yo estoy poniendo sobre 70 cabeceras actualizados por segundo por contenedor. No hay cargos de salida.

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 última versión de Cerebrata almacenamiento en la nube Estudio , v2011.04.23.00 , soportes configuración de caché control sobre los objetos blob individuales. Haz clic derecho en el objeto blob, elegir la opción "Ver / Editar Blob Propiedades" y luego ajustar el valor para el atributo Cache-Control. (Por ejemplo public, max-age=2592000).

Si marca la encabezados HTTP del objeto blob utilizando rizo, verá el encabezado de control de caché vuelto con el valor establecido.

A veces, la respuesta más simple es el mejor. Si lo que desea es administrar una pequeña cantidad de manchas, puede utilizar Gestión Azure para cambiar los encabezados / metadatos para sus gotas.

  1. Haga clic en almacenamiento , a continuación, haga clic en el nombre de la cuenta de almacenamiento.
  2. Haga clic en el Contenedores ficha, a continuación, haga clic en un contenedor.
  3. Haga clic en una burbuja, a continuación, haga clic en Editar en la parte inferior de la pantalla.

En la ventana de edición, puede personalizar la Control de caché , Codificación de contenido , Idioma de Contenido , y mucho más.

Nota: no se puede editar este momento, los datos de la Azure Portal

Esto podría ser demasiado tarde para la respuesta, pero recientemente he querido hacer lo mismo en distinta forma, en el que tengo la lista de imágenes y necesaria para aplicar mediante secuencias de comandos PowerShell (por supuesto con la ayuda de almacenamiento de Azure montaje) La esperanza alguien va a resultar útil en el futuro.

explicación completa dada en Conjunto Azure BLOB Cache-Control utilizando PowerShell guión

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

Definición de almacenamiento de blob Propiedades de control de caché de escritura de PowerShell

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

Aquí está una versión actualizada de la respuesta de Joel Fillmore consumir WindowsAzure.Storage v9.3.3. Tenga en cuenta que ListBlobsSegmentedAsync devuelve un tamaño de página de 5000 por lo que se utiliza el 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;
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top