Padrão de Alojamento de Conteúdo EstáticoStatic Content Hosting pattern

Implemente conteúdo estático num serviço de armazenamento baseado na cloud que o pode oferecer diretamente ao cliente.Deploy static content to a cloud-based storage service that can deliver them directly to the client. Este procedimento pode reduzir a necessidade de instâncias de computação possivelmente dispendiosas.This can reduce the need for potentially expensive compute instances.

Contexto e problemaContext and problem

As aplicações Web incluem, geralmente, alguns elementos de conteúdo estático.Web applications typically include some elements of static content. Este conteúdo estático pode incluir páginas HTML e outros recursos, tais como imagens e documentos que estão disponíveis para o cliente, como parte de uma página HTML (por exemplo, ficheiros JavaScript do lado do cliente, folhas de estilo e imagens inline) ou como transferências separadas (por exemplo, documentos PDF).This static content might include HTML pages and other resources such as images and documents that are available to the client, either as part of an HTML page (such as inline images, style sheets, and client-side JavaScript files) or as separate downloads (such as PDF documents).

Embora os servidores web estão otimizados para renderização dinâmica e a cache de saída, ainda têm de processar pedidos para transferir o conteúdo estático.Although web servers are optimized for dynamic rendering and output caching, they still have to handle requests to download static content. Esse procedimento consome ciclos de processamento que, muitas vezes, poderiam ser mais bem utilizados.This consumes processing cycles that could often be put to better use.

SoluçãoSolution

Na cloud a maioria dos ambientes de alojamento, pode colocar alguns dos recursos e páginas estáticas num serviço de armazenamento de uma aplicação.In most cloud hosting environments, you can put some of an application's resources and static pages in a storage service. O serviço de armazenamento pode servir pedidos para estes recursos, reduzindo a carga sobre os recursos de computação que tratam de outras solicitações da web.The storage service can serve requests for these resources, reducing load on the compute resources that handle other web requests. Normalmente, o custo do armazenamento alojado na cloud é muito inferior às instâncias de computação.The cost for cloud-hosted storage is typically much less than for compute instances.

Ao alojar algumas partes de uma aplicação num serviço de armazenamento, as principais considerações estão relacionadas com a implementação da aplicação e com a proteção dos recursos que não se destinam a estar disponíveis para utilizadores anónimos.When hosting some parts of an application in a storage service, the main considerations are related to deployment of the application and to securing resources that aren't intended to be available to anonymous users.

Problemas e consideraçõesIssues and considerations

Na altura de decidir como implementar este padrão, considere os seguintes pontos:Consider the following points when deciding how to implement this pattern:

  • O serviço de armazenamento alojado tem de expor um ponto final de HTTP ao qual os utilizadores podem aceder para transferir os recursos estáticos.The hosted storage service must expose an HTTP endpoint that users can access to download the static resources. Alguns serviços de armazenamento também suportam HTTPS, pelo que pode alojar recursos de anfitrião nos serviços de armazenamento que exigem SSL.Some storage services also support HTTPS, so it's possible to host resources in storage services that require SSL.

  • Para o máximo de desempenho e disponibilidade, considere utilizar uma rede de entrega de conteúdos (CDN) para colocar em cache o conteúdo do contentor de armazenamento em vários datacenters em todo o mundo.For maximum performance and availability, consider using a content delivery network (CDN) to cache the contents of the storage container in multiple datacenters around the world. No entanto, provavelmente, terá de pagar para utilizar a CDN.However, you'll likely have to pay for using the CDN.

  • As contas de armazenamento são frequentemente georreplicadas por predefinição para proporcionar resiliência contra eventos que podem afetar um datacenter.Storage accounts are often geo-replicated by default to provide resiliency against events that might affect a datacenter. Tal significa que o endereço IP poderá ser alterado, mas o URL permanece o mesmo.This means that the IP address might change, but the URL will remain the same.

  • Quando algum conteúdo se encontra numa conta de armazenamento e outros conteúdos estão numa instância de computação alojados, torna-se mais desafiador para implantar e atualizar a aplicação.When some content is located in a storage account and other content is in a hosted compute instance, it becomes more challenging to deploy and update the application. Poderá ter de realizar implementações separadas e escolher a versão da aplicação e o conteúdo para a gerir mais facilmente — especialmente quando o conteúdo estático inclui ficheiros de script ou componentes da IU.You might have to perform separate deployments, and version the application and content to manage it more easily—especially when the static content includes script files or UI components. No entanto, se apenas recursos estáticos tiverem de ser atualizados, estes poderão simplesmente ser carregados para a conta de armazenamento sem ter de voltar a implementar o pacote de aplicações.However, if only static resources have to be updated, they can simply be uploaded to the storage account without needing to redeploy the application package.

  • Os serviços de armazenamento podem não suportar a utilização de nomes de domínio personalizados.Storage services might not support the use of custom domain names. Neste caso, precisa de especificar o URL completo dos recursos nas ligações, pois vão estar num domínio diferente do conteúdo gerado dinamicamente que contém as ligações.In this case it's necessary to specify the full URL of the resources in links because they'll be in a different domain from the dynamically-generated content containing the links.

  • Os contentores de armazenamento têm de ser configurados para o acesso de leitura público, mas é vital garantir que não estão configurados para o acesso de escrita público para impedir que os utilizadores possam carregar conteúdo.The storage containers must be configured for public read access, but it's vital to ensure that they aren't configured for public write access to prevent users being able to upload content.

  • Considere utilizar um token para controlar o acesso a recursos que não devem estar disponíveis anonimamente ou chave de valet.Consider using a valet key or token to control access to resources that shouldn't be available anonymously. Consulte a padrão da chave Valet para obter mais informações.See the Valet Key pattern for more information.

Quando utilizar este padrãoWhen to use this pattern

Este padrão é útil nas seguintes situações:This pattern is useful for:

  • Minimizar o custo de alojamento de sites e aplicações que contém alguns recursos estáticos.Minimizing the hosting cost for websites and applications that contain some static resources.

  • Minimizar o custo de alojamento para sites que consistem apenas em conteúdo estático e recursos.Minimizing the hosting cost for websites that consist of only static content and resources. Consoante as capacidades do sistema de armazenamento do fornecedor de alojamento, pode ser possível alojar inteiramente um site totalmente estático numa conta de armazenamento.Depending on the capabilities of the hosting provider's storage system, it might be possible to entirely host a fully static website in a storage account.

  • Expor conteúdos e recursos estáticos para aplicações em execução noutros ambientes de alojamento ou nos servidores no local.Exposing static resources and content for applications running in other hosting environments or on-premises servers.

  • Localizar conteúdo em mais de uma área geográfica através de uma rede de entrega de conteúdos que coloca em cache os conteúdos da conta de armazenamento em vários datacenters em todo o mundo.Locating content in more than one geographical area using a content delivery network that caches the contents of the storage account in multiple datacenters around the world.

  • Monitorizar a utilização da largura de banda e os custos.Monitoring costs and bandwidth usage. Utilizar uma conta de armazenamento separada para algum ou todo o conteúdo estático permite que os custos sejam mais facilmente separados dos custos de tempo de execução e do alojamento.Using a separate storage account for some or all of the static content allows the costs to be more easily separated from hosting and runtime costs.

Este padrão pode não ser prático nas seguintes situações:This pattern might not be useful in the following situations:

  • A aplicação tem de realizar algum processamento no conteúdo estático antes de o entregar ao cliente.The application needs to perform some processing on the static content before delivering it to the client. Por exemplo, poderá ser necessário adicionar um carimbo a um documento.For example, it might be necessary to add a timestamp to a document.

  • O volume de conteúdo estático é muito pequeno.The volume of static content is very small. A sobrecarga de obtenção deste conteúdo do armazenamento separado pode prevalecer sobre as vantagens de custo ao separá-lo do recurso de computação.The overhead of retrieving this content from separate storage can outweigh the cost benefit of separating it out from the compute resource.

ExemploExample

O armazenamento do Azure suporta servir conteúdo estático diretamente a partir de um contentor de armazenamento.Azure Storage supports serving static content directly from a storage container. Ficheiros são atendidos por meio de solicitações de acesso anônimo.Files are served through anonymous access requests. Por predefinição, os arquivos tem um URL de um subdomínio core.windows.net, tais como https://contoso.z4.web.core.windows.net/image.png.By default, files have a URL in a subdomain of core.windows.net, such as https://contoso.z4.web.core.windows.net/image.png. Pode configurar um nome de domínio personalizado e utilizar a CDN do Azure para aceder aos ficheiros através de HTTPS.You can configure a custom domain name, and use Azure CDN to access the files over HTTPS. Para obter mais informações, consulte alojar o Web site estático no armazenamento do Azure.For more information, see Static website hosting in Azure Storage.

Entregar partes estáticas de uma aplicação diretamente a partir de um serviço de armazenamento

Alojamento de Web site estático torna os arquivos disponíveis para acesso anónimo.Static website hosting makes the files available for anonymous access. Se precisar de controlar quem pode aceder os ficheiros, pode armazenar ficheiros no armazenamento de Blobs do Azure e, em seguida, gerar assinaturas de acesso partilhado para limitar o acesso.If you need to control who can access the files, you can store files in Azure blob storage and then generate shared access signatures to limit access.

As ligações nas páginas entregues para o cliente tem de especificar o URL completo do recurso.The links in the pages delivered to the client must specify the full URL of the resource. Se o recurso estiver protegido com uma chave valet, como uma assinatura de acesso partilhado, esta assinatura deve ser incluída no URL.If the resource is protected with a valet key, such as a shared access signature, this signature must be included in the URL.

Um aplicativo de exemplo que demonstra a utilização do armazenamento externo para recursos estáticos está disponível no GitHub.A sample application that demonstrates using external storage for static resources is available on GitHub. Este exemplo utiliza ficheiros de configuração para especificar a conta de armazenamento e o contentor que detém o conteúdo estático.This sample uses configuration files to specify the storage account and container that holds the static content.

<Setting name="StaticContent.StorageConnectionString"
         value="UseDevelopmentStorage=true" />
<Setting name="StaticContent.Container" value="static-content" />

A classe Settings, no ficheiro Settings.cs do projeto StaticContentHosting.Web, contém métodos para extrair estes valores e criar um valor de cadeia que contém o URL do contentor da conta de armazenamento na cloud.The Settings class in the file Settings.cs of the StaticContentHosting.Web project contains methods to extract these values and build a string value containing the cloud storage account container URL.

public class Settings
{
  public static string StaticContentStorageConnectionString {
    get
    {
      return RoleEnvironment.GetConfigurationSettingValue(
                              "StaticContent.StorageConnectionString");
    }
  }

  public static string StaticContentContainer
  {
    get
    {
      return RoleEnvironment.GetConfigurationSettingValue("StaticContent.Container");
    }
  }

  public static string StaticContentBaseUrl
  {
    get
    {
      var account = CloudStorageAccount.Parse(StaticContentStorageConnectionString);

      return string.Format("{0}/{1}", account.BlobEndpoint.ToString().TrimEnd('/'),
                                      StaticContentContainer.TrimStart('/'));
    }
  }
}

A classe StaticContentUrlHtmlHelper, no ficheiro StaticContentUrlHtmlHelper.cs, expõe um método denominado StaticContentUrl, que gerará um URL com o caminho para a conta de armazenamento na cloud se o URL transmitido começar com o caráter do caminho da raiz do ASP.NET (~).The StaticContentUrlHtmlHelper class in the file StaticContentUrlHtmlHelper.cs exposes a method named StaticContentUrl that generates a URL containing the path to the cloud storage account if the URL passed to it starts with the ASP.NET root path character (~).

public static class StaticContentUrlHtmlHelper
{
  public static string StaticContentUrl(this HtmlHelper helper, string contentPath)
  {
    if (contentPath.StartsWith("~"))
    {
      contentPath = contentPath.Substring(1);
    }

    contentPath = string.Format("{0}/{1}", Settings.StaticContentBaseUrl.TrimEnd('/'),
                                contentPath.TrimStart('/'));

    var url = new UrlHelper(helper.ViewContext.RequestContext);

    return url.Content(contentPath);
  }
}

O ficheiro Index.cshtml, na pasta Vistas\Início, contém um elemento de imagem que utiliza o método StaticContentUrl para criar o URL para o seu atributo src.The file Index.cshtml in the Views\Home folder contains an image element that uses the StaticContentUrl method to create the URL for its src attribute.

<img src="@Html.StaticContentUrl("~/media/orderedList1.png")" alt="Test Image" />