靜態內容裝載模式

Azure 儲存體

將靜態內容部署至雲端式記憶體服務,以將其直接傳遞至用戶端。 這可減少潛在昂貴計算實例的需求。

內容和問題

Web 應用程式通常包含靜態內容的一些元素。 此靜態內容可能包含 HTML 頁面和其他資源,例如可供用戶端使用的影像和檔,可以是 HTML 頁面的一部分(例如內嵌影像、樣式表單和用戶端 JavaScript 檔案)或個別下載專案(例如 PDF 檔)。

雖然網頁伺服器已針對動態轉譯和輸出快取進行優化,但仍必須處理下載靜態內容的要求。 這會耗用通常可改善使用的處理週期。

解決方案

在大部分的雲端裝載環境中,您可以將一些應用程式的資源和靜態頁面放在記憶體服務中。 記憶體服務可以提供這些資源的要求,減少處理其他 Web 要求的計算資源負載。 雲端裝載記憶體的成本通常遠低於計算實例。

在記憶體服務中裝載應用程式的某些部分時,主要考慮與部署應用程式以及保護不適合匿名使用者使用的資源有關。

問題和考慮

決定如何實作此模式時,請考慮下列幾點:

  • 裝載的記憶體服務必須公開 HTTP 端點,使用者才能存取以下載靜態資源。 某些記憶體服務也支援 HTTPS,因此可以在需要 SSL 的記憶體服務中裝載資源。

  • 為了達到最大效能和可用性,請考慮使用內容傳遞網路 (CDN) 來快取全球多個資料中心的記憶體容器內容。 不過,您可能需要支付使用CDN的費用。

  • 儲存體 帳戶通常是異地復寫,以針對可能影響數據中心的事件提供復原能力。 這表示 IP 位址可能會變更,但 URL 會維持不變。

  • 當某些內容位於記憶體帳戶中,而其他內容位於託管的計算實例中時,部署和更新應用程式會變得更具挑戰性。 您可能必須執行個別的部署,並設定應用程式和內容的版本,以便更輕鬆地管理它,特別是當靜態內容包含腳本檔案或 UI 元件時。 不過,如果只需要更新靜態資源,它們就可直接上傳至記憶體帳戶,而不需要重新部署應用程式套件。

  • 儲存體 服務可能不支援使用自定義功能變數名稱。 在此情況下,您必須在連結中指定資源的完整 URL,因為它們會位於與包含連結的動態產生內容不同的網域中。

  • 記憶體容器必須設定為公用讀取許可權,但請務必確保它們未設定為公用寫入存取,以防止用戶上傳內容。

  • 請考慮使用代客密鑰或令牌來控制不應該匿名使用之資源的存取。 如需詳細資訊, 請參閱代客密鑰模式

使用此模式的時機

此模式適用於:

  • 將包含一些靜態資源之網站和應用程式的裝載成本降至最低。

  • 將只包含靜態內容和資源的網站裝載成本降至最低。 根據裝載提供者記憶體系統的功能,可能會完全裝載記憶體帳戶中的完全靜態網站。

  • 針對在其他主控環境或內部部署伺服器中執行的應用程式公開靜態資源和內容。

  • 使用內容傳遞網路,在多個地理區域中尋找內容,以快取世界各地多個數據中心的記憶體帳戶內容。

  • 監視成本和頻寬使用量。 針對部分或所有靜態內容使用不同的記憶體帳戶,可讓成本更容易與裝載和運行時間成本分開。

在下列情況下,此模式可能沒有用處:

  • 應用程式必須先對靜態內容執行一些處理,才能將它傳遞給用戶端。 例如,可能需要將時間戳新增至檔。

  • 靜態內容的數量非常小。 從個別記憶體擷取此內容的額外負荷,可能超過將其與計算資源分開的成本優勢。

工作負載設計

架構設計人員應該評估靜態內容裝載模式如何用於其工作負載的設計,以解決 Azure 良好架構架構支柱涵蓋的目標和原則。 例如:

要素 此模式如何支援支柱目標
成本優化著重於維持和改善工作負載的投資報酬率。 動態應用程式主機通常比靜態主機更昂貴,因為動態主機可以執行您的自動程式化商業規則。 使用應用程式平臺傳遞靜態內容並不符合成本效益。

- CO:09 流程成本
- CO:10 數據成本
效能效率 可透過調整、數據、程式代碼的優化,有效率地協助您的工作負載 符合需求 卸除外部化主機的責任有助於減輕壅塞,並讓您只使用應用程式平臺來傳遞商業規則。

- PE:07 撰寫基礎結構的程序代碼

如同任何設計決策,請考慮對其他可能以此模式導入之目標的任何取捨。

範例

Azure 儲存體 支援直接從記憶體容器提供靜態內容。 檔案是透過匿名存取要求來提供。 根據預設,檔案的子域 core.windows.net有 URL , 例如 https://contoso.z4.web.core.windows.net/image.png。 您可以設定自定義功能變數名稱,並使用 Azure CDN 透過 HTTPS 存取檔案。 如需詳細資訊,請參閱Azure 儲存體中的靜態網站代管

直接從記憶體服務傳遞應用程式的靜態部分

靜態網站裝載讓檔案可供匿名存取。 如果您需要控制誰可以存取檔案,您可以將檔案儲存在 Azure Blob 記憶體中,然後產生 共用存取簽章 來限制存取權。

傳遞至用戶端之頁面的鏈接必須指定資源的完整 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 中的 類別StaticContentUrlHtmlHelper.cs會公開名為 StaticContentUrl 的方法,如果傳遞至雲端記憶體帳戶的 URL 開頭為 ASP.NET 根路徑字元 (~)。

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 方法來為其屬性建立 URL src

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

下一步

  • 代客金鑰模式。 如果目標資源不應該可供匿名使用者使用,請使用此模式來限制直接存取。
  • Azure 上的無伺服器 Web 應用程式。 參考架構,使用靜態網站裝載與 Azure Functions 來實作無伺服器 Web 應用程式。