--- tags: notes --- # 初探 Timer trigger 的 Azure Functions ## 開發環境 透過命令列開發: - 安裝 .NET 6.0 SDK - 安裝 Azure Functions Core Tools 4.x 版 - Azure CLI 2.4.0 版或更新版本。 - 安裝 Azurite 安裝完畢後請確認 `az`、`func` 和 `azurite` 指令可以被正常執行,如果失敗請重新安裝或手動將 `az` 和 `func` 的目錄加入環境變數。 檢查各項工具的版本是否夠新: ``` > func --version 4.0.4670 > dotnet --list-sdks 6.0.301 > az --version azure-cli 2.39.0 core 2.39.0 > azurite -h ``` ## 建立本機專案 首先啟動 Azure Storage 的模擬器,因為 執行 `func init` 命令,在 CronApp 的資料夾中建立 .NET 的 Azure Functions 專案: ``` > func init CronApp --dotnet ``` 將基於 `Timer trigger` 的 Function 新增至專案: ``` > cd CronApp > func new --name CronApp --template "Timer trigger" ``` `Timer trigger` 依賴 [NCrontab](https://github.com/atifaziz/NCrontab) 套件,這個套件需要透過 `Azure Storage` 儲存一個檔案當作 lock,確保當 Function App 擴展到多個實例時,只使用唯一一個 timer 實例。 此外,如果兩個 Function App 共享相同的 identifying configuration,並且個別使用一個 timer,則只有一個 timer 會運作。 所以接下來先啟動 Azurite 以在本機模擬 Azure Storage: ``` > azurite --queueHost 127.0.0.1 --location azurite_workspace ``` 在上述指令中透過 `--location` 選項,Azurite 所產生的暫存檔會放在 `azurite_workspace` 中。 在執行程式之前,修改一下 `CronApp.cs` 的規則使其每 5 秒觸發一次。 - 第 11 行: 把預設的字串改為 `"*/5 * * * * *"`。`TimerTriggerAttribute` 的原始碼在 [WebJobs.Extensions/Extensions/Timers/TimerTriggerAttribute.cs](https://github.com/Azure/azure-webjobs-sdk-extensions/blob/dev/src/WebJobs.Extensions/Extensions/Timers/TimerTriggerAttribute.cs)。 ```csharp= using System; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; namespace CronApp { public class CronApp { [FunctionName("CronApp")] public void Run([TimerTrigger("*/5 * * * * *")]TimerInfo myTimer, ILogger log) { log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); } } } ``` 執行程式: ``` > func start ``` 每 5 秒 CronApp 會輸出一條訊息: ![](https://i.imgur.com/3HVCifN.png) ## 佈署到 Azure 流程與 [初探 Azure Functions](https://hackmd.io/@blueskyson/azure-functions) 一樣: ``` > az login > az group create --name Functions-rg --location japanwest > az storage account create --name jacklin --location japanwest --resource-group Functions-rg --sku Standard_LRS > az functionapp create --resource-group Functions-rg --consumption-plan-location japanwest --runtime dotnet --functions-version 4 --name jacklin-function --storage-account jacklin > func azure functionapp publish jacklin-function ``` 佈署到 Azure 後透過 log stream 查看 CronApp 是否有被觸發: ![](https://i.imgur.com/ImwOMmW.png) ## 注意事項 NCrontab 已經兩年沒有新的 commit 了,但是 WebJobs.Extensions/Extensions/Timers 還持續有在更新,所以 Azure 團隊應該有在持續維護。