静的コンテンツ ホスティング パターンStatic Content Hosting pattern

静的コンテンツを、クライアントに直接配信できるクラウド ベースのストレージ サービスにデプロイします。Deploy static content to a cloud-based storage service that can deliver them directly to the client. これにより、高額なコンピューティング インスタンスの必要性を低減できる可能性があります。This can reduce the need for potentially expensive compute instances.

コンテキストと問題Context and problem

通常、Web アプリケーションには静的コンテンツの要素が含まれています。Web applications typically include some elements of static content. この静的コンテンツには、HTML ページのほか、クライアントから利用可能な画像やドキュメントが、HTML ページの一部 (インライン画像、スタイル シート、クライアント側 JavaScript ファイルなど) か、個別のダウンロード (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).

Web サーバーは動的レンダリングと出力キャッシュ用に最適化されていますが、静的コンテンツをダウンロードする要求を引き続き処理する必要があります。Although web servers are optimized for dynamic rendering and output caching, they still have to handle requests to download static content. このために消費される処理サイクルは、他の目的のために、より効果的に使用できる可能性があります。This consumes processing cycles that could often be put to better use.

解決策Solution

ほとんどのクラウド ホスティング環境では、いくつかのアプリケーションのリソースと静的なページをストレージ サービスに配置することができます。In most cloud hosting environments, you can put some of an application's resources and static pages in a storage service. ストレージ サービスではこれらのリソースの要求を処理することができ、他の Web 要求を処理するコンピューティング リソースの負荷が軽減されます。The storage service can serve requests for these resources, reducing load on the compute resources that handle other web requests. クラウドでホストされるストレージのコストは、通常、多くのコンピューティング インスタンスのコストよりも安価です。The cost for cloud-hosted storage is typically much less than for compute instances.

アプリケーションの一部をストレージ サービスでホストする場合の主な考慮事項は、アプリケーションのデプロイと、匿名ユーザーへの提供を意図していないリソースのセキュリティ保護に関連します。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.

問題と注意事項Issues and considerations

このパターンの実装方法を決めるときには、以下の点に注意してください。Consider the following points when deciding how to implement this pattern:

  • ホストされるストレージ サービスでは、ユーザーが静的リソースをダウンロードするためにアクセスできる HTTP エンドポイントを公開する必要があります。The hosted storage service must expose an HTTP endpoint that users can access to download the static resources. 一部のストレージ サービスでは、SSL を必要とするストレージ サービス内のリソースをホストできるよう、HTTPS もサポートされています。Some storage services also support HTTPS, so it's possible to host resources in storage services that require SSL.

  • パフォーマンスと可用性を最大化するために、コンテンツ配信ネットワーク (CDN) を使用して、ストレージ コンテナーのコンテンツを世界各地の複数のデータ センターにキャッシュすることを検討してください。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. ただし、CDN を使用するには、通常、料金を支払う必要があります。However, you'll likely have to pay for using the CDN.

  • ストレージ アカウントは、データ センターに影響を与えるイベントが発生した場合の回復性を提供するために、既定で地理的にレプリケートされることが少なくありません。Storage accounts are often geo-replicated by default to provide resiliency against events that might affect a datacenter. つまり、IP アドレスが変更される可能性があります。ただし、URL はそのまま維持されます。This means that the IP address might change, but the URL will remain the same.

  • 一部のコンテンツがストレージ アカウントに配置されており、その他のコンテンツがホストされているコンピューティング インスタンスにある場合、アプリケーションのデプロイや更新がより困難になります。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. 管理を容易にするには、デプロイを個別に行い、アプリケーションとコンテンツのバージョンを管理する必要が生じる場合があります (特に、静的コンテンツにスクリプト ファイルや UI コンポーネントが含まれている場合)。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. ただし、静的リソースだけを更新すればよい場合は、アプリケーション パッケージを再デプロイすることなく、静的リソースだけをストレージ アカウントにアップロードすることもできます。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.

  • ストレージ サービスでは、カスタム ドメイン名の使用がサポートされない場合があります。Storage services might not support the use of custom domain names. その場合は、リンク内にリソースの完全 URL を指定する必要があります。これは、リンクを含んだ動的生成コンテンツから、リソースが別のドメインに配置されることがあるためです。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.

  • ストレージ コンテナーは、パブリック読み取りアクセス用に構成する必要があります。ただし、ユーザーがコンテンツをアップロードできないようにする必要があるため、パブリック書き込みアクセス用には構成しないようにしてください。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.

  • 匿名でのアクセスを許可しないリソースについては、バレット キーやトークンを使用してアクセスを制御することを検討してください。Consider using a valet key or token to control access to resources that shouldn't be available anonymously. 詳細については、「Valet Key pattern」 (バレット キー パターン) を参照してください。See the Valet Key pattern for more information.

このパターンを使用する状況When to use this pattern

このパターンは次の目的に役立ちます。This pattern is useful for:

  • 静的リソースを含んだ Web サイトやアプリケーションのホスティング コストを最小限に抑える。Minimizing the hosting cost for websites and applications that contain some static resources.

  • 静的コンテンツと静的リソースのみで構成される Web サイトのホスティング コストを最小限に抑える。Minimizing the hosting cost for websites that consist of only static content and resources. ホスティング プロバイダーのストレージ システムの機能によっては、完全に静的な Web サイトをストレージ アカウントで完全にホストできる場合もあります。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.

  • 静的リソースと静的コンテンツを、他のホスト環境やオンプレミス サーバーで実行されているアプリケーション用に公開する。Exposing static resources and content for applications running in other hosting environments or on-premises servers.

  • ストレージ アカウントのコンテンツを世界各地の複数のデータ センターにキャッシュするコンテンツ配信ネットワークを使用して、コンテンツを複数の地理的位置に配置する。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.

  • コストと帯域幅の使用状況を監視する。Monitoring costs and bandwidth usage. 静的コンテンツの一部またはすべてに個別のストレージ アカウントを使用すると、ホスティング コストやランタイム コストとの分離がより簡単になります。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.

このパターンは、次の状況では有効でない場合があります。This pattern might not be useful in the following situations:

  • 静的コンテンツをクライアントに配信する前に、アプリケーションで何らかの処理を実行する必要がある。The application needs to perform some processing on the static content before delivering it to the client. たとえば、ドキュメントにタイムスタンプを追加する必要がある場合などです。For example, it might be necessary to add a timestamp to a document.

  • 静的コンテンツの量が非常に少ない。The volume of static content is very small. これらのコンテンツを個別のストレージから取得するためのオーバーヘッドが、コンピューティング リソースから分離することのコスト メリットを上回る恐れがあります。The overhead of retrieving this content from separate storage can outweigh the cost benefit of separating it out from the compute resource.

Example

Azure Storage では、ストレージ コンテナーから直接静的コンテンツを提供できます。Azure Storage supports serving static content directly from a storage container. ファイルは匿名のアクセス要求を通じて提供されます。Files are served through anonymous access requests. 既定では、ファイルにはサブドメインが core.windows.net の URL (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. カスタム ドメイン名を構成し、Azure CDN を使用して、HTTPS 経由でファイルにアクセスすることができます。You can configure a custom domain name, and use Azure CDN to access the files over HTTPS. 詳細については、「Azure Storage での静的 Web サイト ホスティング」を参照してください。For more information, see Static website hosting in Azure Storage.

アプリケーションの静的部分をストレージ サービスから直接配信する

静的 Web サイト ホスティングでは、匿名アクセスでファイルを使用できるようにします。Static website hosting makes the files available for anonymous access. ファイルにアクセスできるユーザーを制御する必要がある場合は、Azure BLOB ストレージにファイルを格納し、共有アクセス署名を生成してアクセスを制限できます。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.

クライアントに配信されるページ内のリンクでは、リソースの完全 URL を指定する必要があります。The links in the pages delivered to the client must specify the full URL of the resource. リソースがバレット キー (共有アクセス署名など) を使用して保護されている場合、この署名は URL に含まれている必要があります。If the resource is protected with a valet key, such as a shared access signature, this signature must be included in the URL.

静的リソース用の外部ストレージの使用方法を示すサンプル アプリケーションは、GitHub で入手できます。A sample application that demonstrates using external storage for static resources is available on GitHub. このサンプルでは、ストレージ アカウントを指定する構成ファイルと、静的コンテンツを保持するコンテナーを使用します。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" />

StaticContentHosting.Web プロジェクトの Settings.cs ファイル内にある Settings クラスには、 これらの値を抽出し、クラウド ストレージ アカウントのコンテナー URL を含んだ文字列値を構築するメソッドが含まれています。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('/'));
    }
  }
}

StaticContentUrlHtmlHelper.cs ファイル内の StaticContentUrlHtmlHelper クラスは、渡された URL が ASP.NET のルート パス文字 (~) で始まる場合に、クラウド ストレージ アカウントへのパスを含んだ URL を生成する、StaticContentUrl というメソッドを公開します。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);
  }
}

Views\Home フォルダー内の Index.cshtml ファイルには、StaticContentUrl メソッドを使用して src 属性の URL を作成する画像要素が含まれています。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" />