azure 的 App Service 設定, App Configuration, Storage Account (Blob) 比較

這三者雖然都跟「儲存資料」或「設定」有關,但在雲端架構中扮演的角色完全不同。

  • Storage Account 是放「檔案」
  • App Service 設定是放「靜態環境變數」
  • App Configuration 則是放「動態、跨服務的配置中心」


1. 三者的核心差異表

特性App Service (appsettings)Azure App ConfigurationStorage Account (Blob)
主要用途存放單一 Web App 的環境變數。集中管理多個服務的設定。存放非結構化資料(圖片、影片、日誌)。
生效方式修改後 Web App 會重啟支援 熱更新 (Hot Reload),不需重啟。需透過 SDK 讀取檔案內容。
適用規模單一小專案。中大型微服務架構、多環境管理。大量靜態檔案或大數據儲存。
功能重點簡單、直接整合在部署流程。版本控制、標籤 (Label)、功能開關 (Feature Flag)。高擴展性、低成本儲存。

2. 詳細分析

Azure App Service (webapp config appsettings)

這是最基礎的作法。你在 Azure Portal 的「環境變數」中設定的內容,會以環境變數的形式注入到你的程式(如 .NET 的 IConfiguration)。

  • 優點: 設定簡單,與 App Service 綁定,安全性高(可參考 Key Vault)。
  • 缺點: 每次改動設定,Web App 就會重新啟動(Restart),這在正式環境可能會造成短暫的服務中斷。

Azure App Configuration

這是專門為微服務複雜專案設計的配置中心。

  • 集中化: 如果你有 10 個 Web App 都共用同一個資料庫連線字串,你不需要去 10 個地方改,只要在 App Configuration 改一次就好。
  • 功能開關 (Feature Flags): 你可以在不重新部署程式的情況下,在 Portal 上點一下就開啟或關閉某個功能。
  • 標籤管理: 可以針對不同環境(如 Development, Production)使用同一個 Key,但給予不同的標籤值。

Storage Account

這通常不建議用來存放一般的「應用程式設定值」。

  • 用途: 如果你的設定是一個超大的 JSON 檔案或是程式碼需要讀取的配置表(例如:全台門市清單、稅率換算表),且這些資料不會頻繁變動,才會放在這裡。
  • 存取: 程式必須透過 BlobServiceClient 去下載並解析檔案,這比讀取環境變數慢且複雜。

3. 實戰建議:我該選哪一個?

  1. 如果你只有一個 Web App,且設定很少改:直接用 App Service 的環境變數 即可。
  2. 如果你有多個服務(Function, Web App, Container)且需要頻繁切換功能開關:請使用 Azure App Configuration,這能讓你管理起來輕鬆很多。
  3. 如果你的「設定」本身是一個大檔案(如 10MB 的規則庫):請放在 Storage Account,並在 App Configuration 中紀錄該檔案的 URL。

小撇步: 無論用哪一個,如果是敏感資訊(密碼、金鑰),請一律存在 Azure Key Vault,然後在 App Configuration 或 App Service 中引用它。


在 Python (特別是使用 Flask 或 Django 等 Web 框架) 中實作 Azure App Configuration 的動態刷新,核心機制是利用 SDK 提供的 on_refresh_callback 或定期檢查 Sentinel Key (哨兵鍵)

與 .NET 的強型別注入不同,Python 需要手動調用 refresh() 方法來檢查配置是否變動。


1. 核心觀念:Sentinel Key (哨兵鍵)

為了效能,我們不會每次請求都去檢查所有設定。我們會定義一個名為 Sentinel 的 Key,當這個 Key 的值改變時,SDK 才會去拉取所有更新。


2. Python 程式碼實作 (以 Flask 為例)

首先,確保安裝必要的套件:

Bash

pip install azure-appconfiguration-provider flask

範例程式碼:

Python

import os
from flask import Flask
from azure.appconfiguration.provider import load_configuration, SentinelKey

app = Flask(__name__)

# 1. 連線字串 (建議放在環境變數中)
CONNECTION_STRING = os.environ.get("AZURE_APPCONFIG_CONNECTION_STRING")

# 2. 設定哨兵鍵 (當此 Key 變動時,觸發刷新)
select_key = SentinelKey("Sentinel", label="dev")

# 3. 載入配置並設定刷新機制
# refresh_on: 監控的鍵
# refresh_interval: 檢查間隔 (秒),這段時間內呼叫 refresh() 不會真的連網
config = load_configuration(
    connection_string=CONNECTION_STRING,
    refresh_on=[select_key],
    refresh_interval=30 
)

@app.route("/")
def index():
    # 4. 每次請求或定期執行 refresh()
    # SDK 會判斷是否超過 refresh_interval,若超過且 Sentinel 變動,則更新 config
    config.refresh()
    
    # 讀取設定值
    message = config.get("GreetingMessage", "Hello World!")
    return f"<h1>{message}</h1>"

if __name__ == "__main__":
    app.run()

3. 實作細節說明

  • refresh_interval: 這非常重要。如果設為 30 秒,那麼在 30 秒內無論你呼叫幾次 config.refresh(),它都不會去連線 Azure,以節省 API 呼叫成本與效能。
  • 非同步支援: 如果你使用的是 FastAPI,可以使用 load_configuration 的非同步版本(需安裝 azure-appconfiguration-provider 的非同步依賴)。
  • 設定層級:
    • 在 Azure Portal 修改 GreetingMessage 後,必須同時去更新 Sentinel 的值(例如把 1.0 改成 1.1)。
    • SDK 偵測到 Sentinel 變了,才會一次把 GreetingMessage 也同步過來。

4. 為什麼在 Python 中不推薦「全自動」刷新?

在 .NET 中有 Middleware 可以自動處理,但在 Python 中,由於其 WSGI/ASGI 的運行機制,通常建議:

  1. 手動觸發: 在 Web Framework 的 before_request 鉤子中呼叫 refresh()
  2. 背景任務: 使用 threading.Timer 定期在背景執行 refresh(),這樣不會阻塞使用者的請求。

接下來的建議

寫一個背景線程 (Background Thread) 的版本,讓 refresh() 在後台自動執行,而不影響 Web 請求的響應速度


這是一個常見的誤解。事實上,Azure Container Apps (ACA) 當然可以使用 appsettings.json

Container Apps 本質上就是執行你的容器映像檔。只要你的程式碼(例如 .NET)邏輯裡有讀取 appsettings.json,它在雲端執行時依然會去讀取該檔案。

為什麼大家會討論這兩者的差異

雖然可以使用 appsettings.json,但在雲原生環境中,我們通常會避免將機密資訊或變動頻繁的設定直接寫死在映像檔裡的 appsettings.json。這時會有幾種層次的處理方式:

1. 容器環境變數 (Environment Variables)

這是最直接的做法。ACA 允許你在部署時設定環境變數。對於 .NET 程式來說,環境變數會自動覆蓋 appsettings.json 中的同名設定。

  • 優點:簡單、快速。
  • 缺點:如果設定值很多,管理起來很零碎。

2. ACA 內建的 Secrets

對於資料庫密碼、API Key 等敏感資訊,ACA 有專門的 Secrets 管理介面。你可以先在 ACA 層級定義 Secret,再將其映射為環境變數讓程式讀取。

3. Azure App Configuration

這是一個外部的中心化設定管理服務。

  • 適用時機: 當你有幾十個微服務(Container Apps),且希望在不重啟程式的情況下,改一個地方就讓所有服務同步更新設定(動態更新)。
  • 整合方式: 程式啟動時會連到 App Configuration 抓取設定,這同樣會覆蓋本地的 appsettings.json

總結建議

如果你只是單一服務,且設定不太會變動,繼續用 appsettings.json 配合 環境變數 覆蓋特定屬性是最平衡的做法。

如果你正在開發複雜的微服務架構,或是需要「功能開關」(Feature Flags),這時才需要考慮引入 Azure App Configuration。所以並不是「只能」用它,而是它提供了更強大的集中管理能力。

對於一般的開發流程:

  1. 開發環境:使用 appsettings.Development.json
  2. 部署到 ACA:將正式環境的資料庫連線字串等,設定在 ACA 的 SecretsConfiguration 區塊,程式執行時會自動優先採用這些雲端設定。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *