無伺服器 Web 應用程式

Microsoft Entra ID
Azure API 管理
Azure Blob 儲存體
Azure 內容傳遞網路
Azure Functions
Azure 監視器

此參考架構會顯示 伺服器 Web 應用程式。 應用程式會從 Azure Blob 儲存體 提供靜態內容,並使用 Azure Functions 實作 API。 API 會從 Azure Cosmos DB 讀取數據,並將結果傳回至 Web 應用程式。

GitHub 標誌此架構的兩個參考實作可在 GitHub 上取得:無人機傳遞應用程式(ARM 和 Azure Pipelines)待辦事項 應用程式(Bicep 和 GitHub Actions)。

架構

此圖顯示無伺服器 Web 應用程式的參考架構。

下載此架構的 Visio 檔案

無伺服器一詞有兩個不同但相關的意義:

  • 後端即服務 (BaaS)。 後端雲端服務,例如資料庫和記憶體,提供可讓用戶端應用程式直接連線到這些服務的 API。
  • 函式即服務 (FaaS)。 在此模型中,「函式」是部署至雲端的程式代碼片段,並在裝載環境中執行,以完全抽象化執行程式碼的伺服器。

這兩個定義都有開發人員和 DevOps 人員不需要部署、設定或管理伺服器的概念。 此參考架構著重於使用 Azure Functions 的 FaaS,不過從 Azure Blob 儲存體 提供 Web 內容可能是 BaaS 的範例。 FaaS 的一些重要特性包括:

  1. 平台會視需要動態配置計算資源。
  2. 以使用量為基礎的定價:您只需支付用來執行程式代碼的計算資源費用。
  3. 計算資源會根據流量進行調整,而開發人員不需要執行任何設定。

當外部觸發程式發生時,會執行函式,例如 HTTP 要求或抵達佇列的訊息。 這讓 無伺服器架構自然成為事件驅動架構樣式 。 若要協調架構中元件之間的工作,請考慮使用訊息代理程式或發佈/子模式。 如需在 Azure 中選擇傳訊技術的說明,請參閱 在傳遞訊息的 Azure 服務之間選擇。

元件

架構包含下列元件:

Blob 儲存體。 靜態 Web 內容,例如 HTML、CSS 和 JavaScript 檔案,會儲存在 Azure Blob 儲存體 中,並使用靜態網站裝載提供給用戶端。 所有動態互動都會透過呼叫後端 API 的 JavaScript 程式代碼進行。 沒有伺服器端程式代碼可轉譯網頁。 靜態網站裝載支援索引檔和自定義 404 錯誤頁面。

CDN。 使用 Azure 內容傳遞網路 (CDN) 快取內容,以降低延遲和更快傳遞內容,以及提供 HTTPS 端點。

函式應用程式Azure Functions 是無伺服器計算選項。 它會使用事件驅動模型,其中觸發程式會叫用一段程序代碼(「函式」)。 在此架構中,當用戶端提出 HTTP 要求時,會叫用 函式。 要求一律會透過 API 閘道路由傳送,如下所述。

API 管理Azure API 管理 提供位於 HTTP 函式前方的 API 閘道。 您可以使用 API 管理 來發佈和管理用戶端應用程式所使用的 API。 使用閘道有助於將前端應用程式與後端 API 分離。 例如,API 管理 可以重寫 URL、在要求到達後端之前轉換要求、設定要求或響應標頭等等。

API 管理 也可以用來實作跨領域考慮,例如:

  • 強制執行使用量配額和速率限制
  • 驗證 OAuth 令牌以進行驗證
  • 開啟跨原始來源要求 (CORS)
  • 快取回應
  • 監視和記錄要求

如果您不需要 API 管理 提供的所有功能,另一個選項是使用 Functions Proxy。 Azure Functions 的這項功能可讓您藉由建立後端函式的路由,為多個函式應用程式定義單一 API 介面。 函式 Proxy 也可以對 HTTP 要求和回應執行有限的轉換。 不過,它們不會提供 API 管理 相同的豐富原則式功能。

Azure Cosmos DBAzure Cosmos DB 是多模型資料庫服務。 在此案例中,函式應用程式會從 Azure Cosmos DB 擷取檔,以回應來自用戶端的 HTTP GET 要求。

Microsoft Entra ID (Microsoft Entra ID)。 使用者使用其 Microsoft Entra ID 認證登入 Web 應用程式。 Microsoft Entra ID 會傳回 API 的存取令牌,Web 應用程式用來驗證 API 要求(請參閱 驗證)。

Azure 監視器Azure 監視器 會收集解決方案中部署之 Azure 服務的效能計量。 藉由在儀錶板中可視化這些專案,您可以了解解決方案的健康情況。 它也會收集應用程式記錄。

Azure PipelinesAzure Pipelines 是持續整合 (CI) 和持續傳遞 (CD) 服務,可建置、測試及部署應用程式。

GitHub Actions。 工作流程 是您在 GitHub 存放庫中設定的自動化程式 (CI/CD)。 您可以使用工作流程,在 GitHub 上建置、測試、封裝、發行或部署任何專案。

案例詳細資料

潛在使用案例

這種無人機交付解決方案非常適合飛機、航空、航空航太和機器人產業。

建議

函式應用程式方案

Azure Functions 支援兩個裝載模型。 使用耗用量計劃時,計算能力會在程式代碼執行時自動配置。 使用 App Service 方案時,會為您的程式代碼配置一組 VM。 App Service 方案會定義 VM 數目和 VM 大小。

請注意,根據上述定義,App Service 方案並非完全 伺服器。 不過,程式設計模型是相同的, 相同的函式程式代碼可以在取用方案和 App Service 方案中執行。

以下是選擇要使用哪一種計劃類型時要考慮的一些因素:

  • 冷啟動。 使用取用方案時,最近未叫用的函式會在下次執行時產生一些額外的延遲。 此額外延遲是由於配置和準備運行時間環境所造成。 它通常是以秒的順序,但取決於數個因素,包括需要載入的相依性數目。 如需詳細資訊,請參閱 瞭解無伺服器冷啟動。 冷啟動通常比異步訊息驅動工作負載(佇列或事件中樞觸發程式)更關心互動式工作負載(HTTP 觸發程式),因為使用者會直接觀察到額外的延遲。
  • 逾時期間。 在取用方案中,函式執行會在可 設定 的時間週期之後逾時(最多 10 分鐘)
  • 虛擬網路隔離。 使用 App Service 方案可讓函式在 App Service 環境執行,這是專用且隔離的裝載環境。
  • 定價模式。 耗用量計劃會依執行次數和資源耗用量來計費(記憶體×運行時間)。 App Service 方案是根據 VM 實例 SKU 每小時計費。 取用方案通常比 App Service 方案便宜,因為您只需支付您使用的計算資源費用。 如果您的流量遇到尖峰和低谷,這尤其如此。 不過,如果應用程式遇到持續大量的輸送量,App Service 方案的成本可能會低於取用方案。
  • 調整大小。 取用模型的優點是,它會根據傳入流量,視需要動態調整規模。 雖然此調整速度很快發生,但仍有一個加速期。 針對某些工作負載,您可能會想要刻意過度布建 VM,以便您可以處理流量高載,且加班時間為零。 在此情況下,請考慮App Service方案。

函式應用程式界限

式應用程式 會裝載一或多個 函式的執行。 您可以使用函式應用程式,將數個函式分組為邏輯單元。 在函式應用程式中,函式會共用相同的應用程式設定、主控方案和部署生命週期。 每個函式應用程式都有自己的主機名。

使用函式應用程式將共用相同生命週期和設定的函式分組。 不共用相同生命週期的函式應該裝載在不同的函式應用程式中。

請考慮採用微服務方法,其中每個函式應用程式代表一個微服務,可能由數個相關函式組成。 在微服務架構中,服務應該具有鬆散結合和高功能凝聚力。 鬆散結合表示您可以變更一個服務,而不需要同時更新其他服務。 凝聚力表示服務具有單一定義完善的用途。 如需這些想法的詳細資訊,請參閱 設計微服務:定義域分析

函式繫結

盡可能使用 Functions 系結 。 系結提供宣告式方式,可將程式代碼連線至數據,並與其他 Azure 服務整合。 輸入系結會從外部數據源填入輸入參數。 輸出系結會將函式的傳回值傳送至數據接收,例如佇列或資料庫。

例如, GetStatus 參考實作中的函式會使用 Azure Cosmos DB 輸入系結。 此系結設定為使用從 HTTP 要求中的查詢字串擷取的查詢參數,在 Azure Cosmos DB 中查閱檔。 如果找到檔,則會以參數的形式傳遞至函式。

[Function("GetStatusFunction")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req,
        [CosmosDBInput(
           databaseName: "%COSMOSDB_DATABASE_NAME%",
           containerName:"%COSMOSDB_DATABASE_COL%",
           Connection  = "COSMOSDB_CONNECTION_STRING",
           Id = "{Query.deviceId}",
           PartitionKey = "{Query.deviceId}")] DeviceState? deviceStatus)
{
  ...
}

藉由使用系結,您不需要撰寫直接與服務交談的程序代碼,這可讓函式程式碼更簡單,也會抽象化數據源或接收的詳細數據。 不過,在某些情況下,您可能需要比系結提供更複雜的邏輯。 在此情況下,請直接使用 Azure 用戶端 SDK。

考量

這些考量能實作 Azure Well-Architected Framework 的要素,其為一組指導原則,可以用來改善工作負載的品質。 如需詳細資訊,請參閱 Microsoft Azure Well-Architected Framework (部分機器翻譯)。

延展性

函數。 針對取用方案,HTTP 觸發程式會根據流量進行調整。 並行函式實例的數目有限制,但每個實例一次可以處理多個要求。 針對 App Service 方案,HTTP 觸發程式會根據 VM 實例數目進行調整,可以是固定值,也可以根據一組自動調整規則自動調整。 如需詳細資訊,請參閱 Azure Functions 調整和裝載

Azure Cosmos DB。 Azure Cosmos DB 的輸送量容量是以 要求單位 (RU) 來測量。 1 RU 輸送量會對應至取得 1KB 檔所需的輸送量。 若要將 Azure Cosmos DB 容器調整為超過 10,000 RU,您必須在建立容器時指定 分割區索引鍵,並在您所建立的每個檔中包含分割區索引鍵 。 如需分割區索引鍵的詳細資訊,請參閱 Azure Cosmos DB 中的數據分割和調整。

API 管理。 API 管理 可以相應放大並支援以規則為基礎的自動調整。 調整流程至少需要 20 分鐘的時間。 如果您的流量為高載,您應該布建您預期的最大高載流量。 不過,自動調整對於處理每小時或每日流量變化很有用。 如需詳細資訊,請參閱自動調整 Azure API 管理 實例

災害復原

此處顯示的部署位於單一 Azure 區域中。 如需災害復原的更有彈性的方法,請利用各種服務中的異地散發功能:

  • API 管理 支援多區域部署,可用來將單一 API 管理 實例分散到任意數目的 Azure 區域。 如需詳細資訊,請參閱如何將 Azure API 管理服務執行個體部署到多個 Azure 區域

  • 使用 流量管理員 將 HTTP 要求路由傳送至主要區域。 如果在該區域中執行的函式應用程式變得無法使用,流量管理員 可以故障轉移至次要區域。

  • Azure Cosmos DB 支援 多個寫入區域,可讓您寫入您新增至 Azure Cosmos DB 帳戶的任何區域。 如果您未啟用多寫入,您仍然可以故障轉移主要寫入區域。 Azure Cosmos DB 用戶端 SDK 和 Azure 函式系結會自動處理故障轉移,因此您不需要更新任何應用程式組態設定。

安全性

安全性可提供保證,以避免刻意攻擊和濫用您寶貴的資料和系統。 如需詳細資訊,請參閱安全性要素的概觀

驗證

GetStatus參考實作中的 API 會使用 Microsoft Entra ID 來驗證要求。 Microsoft Entra ID 支援 OpenID 連線 通訊協定,這是建置在 OAuth 2 通訊協定之上的驗證通訊協定。

在此架構中,用戶端應用程式是在瀏覽器中執行的單頁應用程式 (SPA)。 這種類型的用戶端應用程式無法保留用戶端密碼或授權碼隱藏,因此隱含授與流程是適當的。 (請參閱我應該使用哪一個 OAuth 2.0 流程? 以下是整體流程:

  1. 用戶按下 Web 應用程式中的 [登入] 連結。
  2. 瀏覽器會重新導向 Microsoft Entra 登入頁面。
  3. 使用者登入。
  4. Microsoft Entra ID 會將重新導向回用戶端應用程式,包括 URL 片段中的存取令牌。
  5. 當 Web 應用程式呼叫 API 時,它會在驗證標頭中包含存取令牌。 應用程式識別碼會以存取令牌中的物件 ('aud') 宣告的形式傳送。
  6. 後端 API 會驗證存取令牌。

若要設定驗證:

  • 在 Microsoft Entra 租用戶中註冊應用程式。 這會產生應用程式識別碼,用戶端會與登入URL一起包含此標識碼。

  • 在函式應用程式內啟用 Microsoft Entra 驗證。 如需詳細資訊,請參閱 Azure App Service 中的驗證與授權

  • 將 validate-jwt 原則新增至 API 管理,藉由驗證存取令牌預先授權要求。

如需詳細資訊,請參閱 GitHub 自述檔

建議在用戶端應用程式和後端 API 的 Microsoft Entra 識別碼中建立個別的應用程式註冊。 授與用戶端應用程式呼叫 API 的許可權。 此方法可讓您彈性地定義多個 API 和用戶端,並控制每個 API 的許可權。

在 API 中,使用 範圍 來讓應用程式更精細地控制他們向使用者要求的許可權。 例如,API 可能有 ReadWrite 範圍,而特定用戶端應用程式可能會要求使用者只授權 Read 許可權。

授權

在許多應用程式中,後端 API 必須檢查使用者是否有權執行指定的動作。 建議您使用 宣告型授權,其中身分識別提供者會傳達使用者的相關信息(在此案例中為 Microsoft Entra ID),並用來做出授權決策。 例如,當您在 Microsoft Entra ID 中註冊應用程式時,可以定義一組應用程式角色。 當使用者登入應用程式時,Microsoft Entra ID 會包含 roles 使用者已授與之每個角色的宣告,包括透過群組成員資格繼承的角色。

Microsoft Entra ID 傳回給用戶端的標識碼令牌包含一些使用者的宣告。 在函式應用程式中,這些宣告可在要求的 X-MS-CLIENT-PRINCIPAL 標頭中取得。 不過,從系結數據讀取這項資訊會更簡單。 對於其他宣告,請使用 Microsoft Graph 查詢 Microsoft Entra ID。 (用戶必須在登入時同意此動作。

如需詳細資訊,請參閱 使用用戶端身分識別

CORS

在此參考架構中,Web 應用程式和 API 不會共用相同的來源。 這表示當應用程式呼叫 API 時,它是跨原始來源要求。 瀏覽器安全性可防止網頁對另一個網域提出AJAX要求。 這項限制稱為 相同原始來源原則 ,並防止惡意網站從另一個網站讀取敏感數據。 若要啟用跨原始來源要求,請將跨原始來源資源分享 (CORS) 原則新增至 API 管理 閘道:

<cors allow-credentials="true">
    <allowed-origins>
        <origin>[Website URL]</origin>
    </allowed-origins>
    <allowed-methods>
        <method>GET</method>
    </allowed-methods>
    <allowed-headers>
        <header>*</header>
    </allowed-headers>
</cors>

在此範例中 ,allow-credentials 屬性為 true。 這會授權瀏覽器傳送具有要求的認證(包括 Cookie)。 否則,瀏覽器預設不會傳送具有跨原始來源要求的認證。

注意

請非常小心將允許認證設定true,因為這表示網站可以代表使用者將使用者的認證傳送至您的 API,而不需要使用者知道。 您必須信任允許的來源。

強制使用 HTTPS

為了達到最大安全性,在整個要求管線中都需要 HTTPS:

  • CDN。 Azure CDN 預設支援子域上的 *.azureedge.net HTTPS。 若要在 CDN 中啟用自訂功能變數名稱的 HTTPS,請參閱 教學課程:在 Azure CDN 自定義網域上設定 HTTPS。

  • 靜態網站裝載。 在 儲存體 帳戶上啟用 [需要安全傳輸] 選項。 啟用此選項時,記憶體帳戶只允許來自安全 HTTPS 連線的要求。

  • API 管理。 將 API 設定為僅使用 HTTPS 通訊協定。 您可以在 Azure 入口網站 或透過 Resource Manager 樣本來設定:

    {
        "apiVersion": "2018-01-01",
        "type": "apis",
        "name": "dronedeliveryapi",
        "dependsOn": [
            "[concat('Microsoft.ApiManagement/service/', variables('apiManagementServiceName'))]"
        ],
        "properties": {
            "displayName": "Drone Delivery API",
            "description": "Drone Delivery API",
            "path": "api",
            "protocols": [ "HTTPS" ]
        },
        ...
    }
    
  • Azure Functions。 啟用 [僅限 HTTPS] 設定。

鎖定函式應用程式

對函式的所有呼叫都應該通過 API 閘道。 您可以達成此目的,如下所示:

  • 將函式應用程式設定為需要函式金鑰。 API 管理 閘道會在呼叫函式應用程式時包含函式金鑰。 這可防止用戶端直接呼叫 函式,而略過閘道。

  • API 管理 閘道具有靜態IP位址。 限制 Azure 函式只允許來自該靜態 IP 位址的呼叫。 如需詳細資訊,請參閱 Azure App Service 靜態 IP 限制。 (此功能僅適用於標準層服務。

保護應用程式秘密

請勿在您的程式代碼或組態檔中儲存應用程式秘密,例如資料庫認證。 請改用儲存在 Azure 中加密的應用程式設定。 如需詳細資訊,請參閱 Azure App 服務 和 Azure Functions 中的安全性。

或者,您可以將應用程式秘密儲存在 金鑰保存庫 中。 這可讓您集中儲存秘密、控制其散發,以及監視存取秘密的方式和時間。 如需詳細資訊,請參閱設定 Azure Web 應用程式從 金鑰保存庫 讀取秘密。 不過,請注意,Functions 觸發程式和系結會從應用程式設定載入其組態設定。 沒有內建方式可設定觸發程式和系結以使用 金鑰保存庫 秘密。

DevOps

前端部署

此參考架構的前端是單一頁面應用程式,JavaScript 會存取無伺服器後端 API,以及提供快速使用者體驗的靜態內容。 以下是這類應用程式的一些重要考慮:

  • 使用全域就緒CDN,將應用程式統一部署至具有全域就緒CDN的地理區域上的使用者,並裝載在雲端上的靜態內容。 這可避免專用網頁伺服器的需求。 請閱讀 整合 Azure 記憶體帳戶與 Azure CDN 以開始使用。 使用 HTTPS 保護您的應用程式。 如需其他建議,請閱讀使用內容傳遞網路的最佳做法。
  • 使用快速且可靠的 CI/CD 服務,例如 Azure PipelinesGitHub Actions,自動建置和部署每個來源變更。 來源必須位於在線版本控制系統中。 如需 Azure Pipelines 的詳細資訊,請參閱 建立您的第一個管線。 若要深入瞭解適用於 Azure 的 GitHub Actions,請參閱 將應用程式部署至 Azure
  • 壓縮您的網站檔案,以減少CDN上的頻寬耗用量,並改善效能。 Azure CDN 允許 在邊緣伺服器上即時壓縮。 或者,此參考架構中的部署管線會在將檔案部署至 Blob 記憶體之前先壓縮盤案。 這可減少記憶體需求,並讓您選擇壓縮工具,而不論任何CDN限制為何。
  • CDN 應該能夠 清除其快取 ,以確保所有使用者都能提供最新的內容。 如果建置和部署進程不是不可部分完成的,則需要快取清除,例如,如果舊檔案取代為相同原始資料夾中新建的檔案。
  • 不同的快取策略,例如使用目錄的版本設定,可能不需要CDN清除。 此前端應用程式中的組建管線會為每個新建置的版本建立新的目錄。 此版本會以不可部分完成的單位的形式上傳至 Blob 記憶體。 只有在完成的部署之後,Azure CDN 才會指向這個新版本。
  • 藉由快取資源文件來延長一段時間,跨越數個月,以增加快取 TTL。 若要確定快取的檔案在變更時會更新,請在重建檔案時指紋檔名。 此前端應用程式會指紋所有檔案,但公用檔案除外,例如 index.html。 由於index.html經常更新,因此它會反映導致快取重新整理的已變更檔名。 如需詳細資訊,請參閱管理 Azure CDN 中 Web 內容的到期日。

後端部署

若要部署函式應用程式,建議您使用 套件檔案 (「從套件執行」)。 使用此方法,您會將 zip 檔案上傳至 Blob 儲存體 容器,而 Functions 運行時間會將 zip 檔案掛接為唯讀文件系統。 這是不可部分完成的作業,可減少失敗部署將讓應用程式處於不一致狀態的機會。 它也可以改善冷啟動時間,特別是針對Node.js應用程式,因為所有檔案都會一次交換。

API 版本設定

API 是服務與客戶端之間的合約。 在此架構中,API 合約定義於 API 管理 層。 API 管理 支援兩個不同的但互補的版本控制概念

  • 版本 可讓 API 取用者根據其需求選擇 API 版本,例如 v1 與 v2。

  • 修訂可讓 API 系統管理員在 API 中進行非重大變更,並部署這些變更,以及變更記錄,以通知 API 取用者變更。

如果您在 API 中進行重大變更,請在 API 管理 中發佈新版本。 在個別的函式應用程式中,與原始版本並存部署新版本。 這可讓您將現有的用戶端移轉至新的 API,而不會中斷用戶端應用程式。 最後,您可以取代舊版。 API 管理 支援數版本設定配置:URL 路徑、HTTP 標頭或查詢字串。 如需一般 API 版本設定的詳細資訊,請參閱 建立 RESTful Web API 的版本設定。

對於未中斷 API 變更的更新,請將新版本部署至相同函式應用程式中的預備位置。 確認部署成功,然後將預備版本與生產版本交換。 在 API 管理 中發佈修訂。

成本最佳化

成本最佳化是關於考慮如何減少不必要的費用,並提升營運效率。 如需詳細資訊,請參閱成本最佳化要素的概觀

使用 Azure 定價計算機來預估成本。 請考慮這些點,以優化此架構的成本。

Azure Functions

Azure Functions 支援兩個裝載模型。

  • 使用情況方案

    計算能力會在程式代碼執行時自動配置。

  • App Service 方案。

    系統會為您的程式代碼配置一組 VM。 此方案會定義 VM 數目和 VM 大小。

在此架構中,用戶端發出 HTTP 要求時會叫用函式。 因為此使用案例中預期不會有固定的高容量輸送量, 因此建議您使用耗用量方案 ,因為您只需支付所使用的計算資源費用。

Azure Cosmos DB

Azure Cosmos DB 會按小時計費,以取得布建的輸送量和已取用的記憶體。 布建的輸送量以每秒要求單位(RU/秒)表示,這可用於一般資料庫作業,例如插入、讀取。 價格是以您保留的 RU/秒容量為基礎。

儲存體 會針對儲存數據和索引所使用的每個 GB 計費。

如需詳細資訊,請參閱 Azure Cosmos DB 定價模型

在此架構中,函式應用程式會從 Azure Cosmos DB 擷取檔,以回應來自用戶端的 HTTP GET 要求。 在此情況下,Azure Cosmos DB 符合成本效益,因為讀取作業比以 RU/秒表示的寫入作業便宜得多。

內容傳遞網路

計費費率可能會根據來源伺服器的位置,根據將內容傳遞給終端使用者的位置,計費區域有所不同。 用戶端的實體位置不是計費區域。 叫用 CDN 的任何 HTTP 或 HTTPS 要求都是可計費的事件,其中包含所有回應類型:成功、失敗或其他。 不同的回應可能會產生不同的流量數量。

在此參考架構中,部署位於單一 Azure 區域。

若要降低成本,請考慮在較長時間內快取資源檔,並在內容上設定最長的TTL,藉以增加快取TTL。

如需詳細資訊,請參閱 Microsoft Azure Well-Architected Framework 中的成本一節。

部署此案例

若要部署此架構的 參考實作,請參閱 GitHub 自述檔

下一步

產品檔案:

學習課程模組:

若要深入瞭解參考實作,請參閱 程式代碼逐步解說:使用 Azure Functions 的無伺服器應用程式。

相關指引: