정적 콘텐츠 호스팅 패턴

Azure Storage

정적 콘텐츠를 클라이언트에 직접 제공할 수 있는 클라우드 기반 스토리지 서비스에 배포합니다. 이렇게 하면 잠재적으로 비용이 많이 드는 컴퓨팅 인스턴스의 필요성을 줄일 수 있습니다.

컨텍스트 및 문제점

웹 애플리케이션에는 일반적으로 정적 콘텐츠의 일부 요소가 포함됩니다. 이 정적 콘텐츠에는 HTML 페이지, 그리고 HTML 페이지의 일부(예: 인라인 이미지, 스타일시트 및 클라이언트 쪽 JavaScript 파일) 혹은 별도의 다운로드(예: PDF 문서)로 클라이언트에서 사용할 수 있는 이미지 및 문서와 같은 기타 리소스가 포함될 수 있습니다.

웹 서버는 동적 렌더링 및 출력 캐싱에 최적화되어 있지만 정적 콘텐츠 다운로드 요청을 처리해야 합니다. 이렇게 하면 더 잘 사용할 수 있는 처리 주기가 소비됩니다.

솔루션

대부분의 클라우드 호스팅 환경에서 일부 애플리케이션의 리소스 및 정적 페이지를 스토리지 서비스에 배치할 수 있습니다. 스토리지 서비스는 이러한 리소스에 대한 요청을 처리함으로써 다른 웹 요청을 처리하는 컴퓨팅 리소스에 대한 부하를 줄일 수 있습니다. 클라우드 호스팅 스토리지에 대한 비용은 일반적으로 컴퓨팅 인스턴스에 비해 훨씬 적습니다.

스토리지 서비스에서 애플리케이션의 일부 부분을 호스팅하는 경우 기본 고려 사항은 애플리케이션 배포 및 익명 사용자가 사용할 수 없는 리소스 보호와 관련이 있습니다.

문제 및 고려 사항

이 패턴을 구현할 방법을 결정할 때 다음 사항을 고려하세요.

  • 호스트된 스토리지 서비스는 사용자가 정적 리소스를 다운로드하기 위해 액세스할 수 있는 HTTP 엔드포인트를 노출해야 합니다. 일부 스토리지 서비스는 HTTPS도 지원하므로 SSL이 필요한 스토리지 서비스에서 리소스를 호스트할 수 있습니다.

  • 최대 성능 및 가용성을 위해 CDN(콘텐츠 배달 네트워크)을 사용하여 전 세계 여러 데이터 센터에서 스토리지 컨테이너의 콘텐츠를 캐시하는 것이 좋습니다. 그러나 CDN 사용에 대한 비용을 지불해야 할 수 있습니다.

  • 스토리지 계정은 데이터 센터에 영향을 줄 수 있는 이벤트에 대한 복원력을 제공하기 위해 기본적으로 지리적으로 복제되는 경우가 많습니다. 즉, IP 주소가 변경될 수 있지만 URL은 동일하게 기본.

  • 스토리지 계정에 있는 콘텐츠도 있고, 호스트된 컴퓨팅 인스턴스에 있는 콘텐츠도 있는 경우, 애플리케이션을 배포하고 업데이트하는 것이 더 어려워집니다. 정적 콘텐츠에 스크립트 파일 또는 UI 구성 요소가 포함되어 있는 경우에 특히, 보다 쉬운 관리를 위해 별도 배포를 수행하고, 애플리케이션 및 콘텐츠의 버전을 관리해야 할 수 있습니다. 그러나 정적 리소스만 업데이트해야 하는 경우 애플리케이션 패키지를 다시 배포하지 않고도 스토리지 계정에 업로드할 수 있습니다.

  • 스토리지 서비스는 사용자 지정 do기본 이름 사용을 지원하지 않을 수 있습니다. 이 경우 링크가 포함된 동적으로 생성된 콘텐츠와는 다른 기본 있으므로 링크에 있는 리소스의 전체 URL을 지정해야 합니다.

  • 스토리지 컨테이너는 공용 읽기 액세스를 위해 구성해야 하지만 사용자가 콘텐츠를 업로드할 수 없도록 공용 쓰기 액세스에 대해 구성되지 않도록 하는 것이 중요합니다.

  • 발레 키 또는 토큰을 사용하여 익명으로 사용할 수 없는 리소스에 대한 액세스를 제어하는 것이 좋습니다. 자세한 내용은 발레 키 패턴을 참조하세요.

이 패턴을 사용해야 하는 경우

이 패턴은 다음의 경우에 유용합니다.

  • 일부 정적 리소스를 포함하는 웹 사이트 및 애플리케이션에 대한 호스팅 비용을 최소화합니다.

  • 정적 콘텐츠 및 리소스로만 구성된 웹 사이트의 호스팅 비용을 최소화합니다. 호스팅 공급자의 스토리지 시스템의 기능에 따라 스토리지 계정에서 완전히 정적 웹 사이트를 완전히 호스트할 수 있습니다.

  • 다른 호스팅 환경 또는 온-프레미스 서버에서 실행되는 애플리케이션에 대한 정적 리소스 및 콘텐츠 노출

  • 전 세계 여러 데이터 센터에 스토리지 계정의 콘텐츠를 캐시하는 콘텐츠 전송 네트워크를 사용하여 둘 이상의 지리적 영역에 콘텐츠를 배치할 경우

  • 비용 및 대역폭 사용량 모니터링 정적 콘텐츠의 일부나 전체에 대해 별도 스토리지 계정을 사용하면 호스팅 및 런타임 비용에서 콘텐츠 비용을 보다 쉽게 분리할 수 있습니다.

이 패턴은 다음과 같은 경우에 유용하지 않을 수 있습니다.

  • 애플리케이션은 정적 콘텐츠를 클라이언트에 배달하기 전에 몇 가지 처리를 수행해야 합니다. 예를 들어 문서에 타임스탬프를 추가해야 할 수 있습니다.

  • 정적 콘텐츠의 볼륨이 매우 작습니다. 이 콘텐츠를 별도의 스토리지에서 검색하는 오버헤드는 컴퓨팅 리소스에서 분리하는 비용의 이점보다 클 수 있습니다.

워크로드 디자인

설계자는 워크로드 디자인에서 정적 콘텐츠 호스팅 패턴을 사용하여 Azure 잘 설계된 프레임워크 핵심 요소에서 다루는 목표와 원칙을 해결하는 방법을 평가해야 합니다. 예시:

핵심 요소 이 패턴이 핵심 목표를 지원하는 방법
비용 최적화는 워크로드의 투자 수익률을 유지하고 개선하는 데 중점을 줍니다. 동적 호스트는 코딩된 비즈니스 논리를 실행할 수 있으므로 동적 애플리케이션 호스트는 일반적으로 정적 호스트보다 비용이 더 많이 듭니다. 애플리케이션 플랫폼을 사용하여 정적 콘텐츠를 제공하는 것은 비용 효율적이지 않습니다.

- CO:09 흐름 비용
- CO:10 데이터 비용
성능 효율성은 크기 조정, 데이터, 코드의 최적화를 통해 워크로드가 수요를 효율적으로 충족하는 데 도움이 됩니다. 외부화된 호스트에 대한 책임을 오프로드하면 혼잡을 완화하고 애플리케이션 플랫폼을 사용하여 비즈니스 논리를 제공할 수 있습니다.

- PE:07 인프라 코딩

디자인 결정과 마찬가지로 이 패턴으로 도입될 수 있는 다른 핵심 요소의 목표에 대한 절충을 고려합니다.

예시

Azure Storage는 스토리지 컨테이너에서 직접 정적 콘텐츠 제공을 지원합니다. 파일은 익명 액세스 요청을 통해 제공됩니다. 기본적으로 파일에는 https://contoso.z4.web.core.windows.net/image.png와 같이 core.windows.net의 하위 도메인에 URL이 있습니다. 사용자 지정 do기본 이름을 구성하고 Azure CDN을 사용하여 HTTPS를 통해 파일에 액세스할 수 있습니다. 자세한 내용은 Azure Storage에서 정적 웹 사이트 호스팅을 참조하세요.

스토리지 서비스에서 직접 애플리케이션의 정적 부분 제공

정적 웹 사이트 호스팅은 파일을 익명으로 액세스할 수 있도록 합니다. 파일에 액세스할 수 있는 사용자를 제어해야 하는 경우 Azure Blob Storage에 파일을 저장한 다음 공유 액세스 서명을 생성하여 액세스를 제한할 수 있습니다.

클라이언트에 배달된 페이지의 링크는 리소스의 전체 URL을 지정해야 합니다. 리소스가 공유 액세스 서명과 같은 발레 키로 보호되는 경우 이 서명은 URL에 포함되어야 합니다.

정적 리소스에 외부 스토리지를 사용하는 방법을 보여 주는 샘플 애플리케이션은 GitHub에서 사용할 수 있습니다. 이 샘플에서는 구성 파일을 사용하여 정적 콘텐츠를 보유하는 스토리지 계정 및 컨테이너를 지정합니다.

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

Settings StaticContentHosting.Web 프로젝트의 파일 설정.cs 클래스에는 이러한 값을 추출하고 클라우드 스토리지 계정 컨테이너 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 blobServiceClient = new BlobServiceClient(StaticContentStorageConnectionString);

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

StaticContentUrlHtmlHelper.cs 파일의 클래스는 StaticContentUrlHtmlHelper 전달된 URL이 ASP.NET 루트 경로 문자(~)로 시작하는 경우 클라우드 스토리지 계정의 경로를 포함하는 URL을 생성하는 메서드 StaticContentUrl 를 노출합니다.

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을 만드는 이미지 요소가 포함되어 있습니다.

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

다음 단계

  • 발레 키 패턴입니다. 대상 리소스를 익명 사용자가 사용할 수 없는 경우 이 패턴을 사용하여 직접 액세스를 제한합니다.
  • Azure의 서버리스 웹 애플리케이션. Azure Functions와 함께 정적 웹 사이트 호스팅을 사용하여 서버리스 웹앱을 구현하는 참조 아키텍처입니다.