Azure Functions 最佳实践全解析
在云原生应用开发中,Azure Functions 是一个强大的工具。本文将深入探讨 Azure Functions 的一些重要最佳实践,帮助开发者更好地使用 Azure Functions,克服其局限性,并将工作负载从本地迁移到无服务器环境。
1. 使用 IAsyncCollector 函数向队列添加多条消息
在某些场景下,客户端应用(如桌面应用、移动应用或网站)可能会在单个请求中发送多条记录。后端应用需要有机制能一次性异步创建多个队列消息。
准备工作
:
- 若尚未创建存储账户,可使用 Azure 门户创建。
- 若未安装 Microsoft Storage Explorer,可从 http://storageexplorer.com/ 安装。
操作步骤
:
1. 创建一个新的 HTTP 触发器,命名为 BulkDeviceRegistrations,并将授权级别设置为匿名。
2. 用以下代码替换默认代码并保存:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log )
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string Device = string.Empty;
for(int nIndex=0;nIndex<data.devices.Count;nIndex++)
{
Device = Convert.ToString(data.devices[nIndex]);
log.LogInformation("devices data" + Device);
}
return (ActionResult)new OkObjectResult("Program has been executed Successfully.");
}
- 创建 Azure 队列存储输出绑定。点击保存,导航到“集成”选项卡,点击“新建输出”按钮,选择 Azure 队列存储输出绑定,然后点击“选择”按钮。
- 在 Azure 队列存储输出步骤中,提供消息参数名称和队列名称,并在存储账户连接下拉列表中选择存储账户,最后点击保存。
- 点击保存并导航到 Azure 函数的代码编辑器,添加以下代码以保存消息到队列:
public static async Task<IActionResult> Run(HttpRequest req, ILogger log, IAsyncCollector<string> outputDeviceQueue )
{
//...
for(int nIndex=0;nIndex<data.devices.Count;nIndex++)
{
Device = Convert.ToString(data.devices[nIndex]);
outputDeviceQueue.AddAsync(Device);
}
//...
}
- 从门户的“测试”选项卡运行该函数,使用以下输入请求 JSON:
{
"devices": [
{
"type": "laptop",
"brand": "lenovo",
"model": "T440"
},
{
"type": "mobile",
"brand": "Mi",
"model": "Red Mi 4"
}
]
}
- 点击“运行”按钮测试功能。打开 Azure Storage Explorer,导航到名为 devicequeue 的队列,应能看到两条记录。
补充说明
:
若想同步存储多条消息,也可使用 ICollector 接口。这两个接口都包含可接受消息集合并将其创建为队列消息的方法。
2. 使用 Azure 函数和队列触发器实现防御性应用
即使应用经过多次不同环境的测试,仍可能因不可预见的原因而失败。因此,确保应用在出现错误或意外问题时发出警报是很好的做法。
准备工作
:
- 若未创建存储账户,使用 Azure 门户创建。
- 若未安装 Azure Storage Explorer,从 http://storageexplorer.com/ 安装。
操作步骤
:
1.
开发 C# 控制台应用程序
:
- 使用 .NET Core C# 语言创建一个新的控制台应用程序,并创建一个名为 StorageConnectionString 的应用设置键,其值为存储账户连接字符串(可从存储账户的“访问密钥”刀片获取)。
- 使用以下命令安装配置和队列存储 NuGet 包:
Install-Package Microsoft.Azure.Storage.Queue
Install-Package System.Configuration.ConfigurationManager
Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.Json
- 在 program.cs 文件中添加以下命名空间:
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Queue;
using System.Configuration;
using Microsoft.Extensions.Configuration;
using System.IO;
- 添加以下函数并在 Main 方法中调用:
static void CreateQueueMessages()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(configuration.GetConnectionString("StorageConnectionString"));
CloudQueueClient queueclient = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueclient.GetQueueReference("myqueuemessages");
queue.CreateIfNotExists();
CloudQueueMessage message = null;
for(int nQueueMessageIndex = 0; nQueueMessageIndex <= 100; nQueueMessageIndex++)
{
message = new CloudQueueMessage(Convert.ToString(nQueueMessageIndex));
queue.AddMessage(message);
Console.WriteLine(nQueueMessageIndex);
}
}
-
开发 Azure 函数队列触发器
:
- 使用队列触发器模板创建一个名为 ProcessData 的新 Azure 函数,并将队列名称设置为 myqueuemessages。
- 用以下代码替换默认代码:
using System;
public static void Run(string myQueueItem, ILogger log)
{
if(Convert.ToInt32(myQueueItem)>50)
{
throw new Exception(myQueueItem);
}
else
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
}
}
-
运行测试
:
- 按 Ctrl + F5 执行控制台应用程序,导航到 Azure Storage Explorer 查看队列内容。
- 片刻后,应能在 myqueuemessages 队列中看到消息。目前,Azure 门户和 Storage Explorer 显示前 32 条消息,若要查看所有消息,需使用 C# 存储 SDK。
- 还应看到一个名为 myqueuemessages-poison 的新(毒药)队列,其中包含另外 50 条队列消息。Azure 函数运行时会自动创建新队列并添加未被 Azure Functions 正确读取的消息。
补充说明
:
在将队列消息推送到毒药队列之前,Azure 函数运行时会尝试拾取并处理该消息 5 次。可通过在 Run 方法中添加一个 int 类型的新 dequecount 参数并记录其值来了解此过程。
3. 通过定期预热应用避免冷启动
Azure Functions 有三种托管计划:应用服务计划、消耗计划和高级计划。使用消耗计划时,开发者面临的一个问题是冷启动,即当一段时间没有请求时,启动 Azure 函数来处理请求。
准备工作
:
需要一个具有以下触发器的函数应用:
- 一个名为 HttpAlive 的 HTTP 触发器。
- 一个名为 KeepFunctionAppWarm 的定时器触发器,每五分钟运行一次并向 HttpAlive HTTP 触发器发出 HTTP 请求。
操作步骤
:
1.
创建 HTTP 触发器
:
创建一个新的 HTTP 触发器,命名为 HttpAlive,并用以下代码替换默认代码:
using System.Net;
using Microsoft.AspNetCore.Mvc;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
return (ActionResult)new OkObjectResult($"Hello User! Thanks for keeping me Warm");
}
-
创建定时器触发器
:
- 点击“+”图标,搜索“定时器”,然后点击“定时器触发器”按钮。
- 在“新建函数”弹出窗口中提供详细信息,调度使用 CRON 表达式确保定时器触发器每五分钟自动触发。
- 在代码编辑器中粘贴以下代码并保存更改,确保将 < > 替换为实际的函数应用名称:
using System;
public async static void Run(TimerInfo myTimer, ILogger log)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync("https://<FunctionAppName>>.azurewebsites.net/api/HttpALive");
}
}
4. 使用类库在 Azure 函数之间共享代码
若已开发了一个通用库,希望在 Azure 函数应用中重用其功能,可按以下步骤操作。
操作步骤
:
1. 使用 Visual Studio 创建一个新的类库应用程序。
2. 创建一个名为 Helper 的新类,并在新类文件中粘贴以下代码:
namespace Utilities
{
public class Helper
{
public static string GetReusableFunctionOutput()
{
return "This is an output from a Reusuable Library across functions";
}
}
}
- 将构建配置更改为“发布”并构建应用程序,以创建将在 Azure 函数中使用的 .dll 文件。
- 点击“应用服务编辑器”按钮(位于“平台功能”选项卡的“开发工具”部分),导航到要使用该库的函数应用的应用服务编辑器。
- 在 WWWROOT 下的空白区域右键单击,创建一个新的 bin 文件夹。
- 点击“新建文件夹”项后,在出现的文本框中输入“bin”。
- 右键单击 bin 文件夹,选择“上传文件”选项,上传在 Visual Studio 中创建的 .dll 文件。
- 导航到要使用共享方法的 Azure 函数。例如,有两个 Azure 函数(一个 HTTP 触发器和一个定时器触发器)。
-
导航到 ReusableMethodCaller1 函数,进行以下更改:
- 在 ReusableMethodCaller1 Azure 函数的 run.csx 方法中添加新的 #r 指令:
#r "../bin/Reusability.dll"
- 添加新的命名空间:
using Utilities;
通过以上这些最佳实践,开发者可以更高效地使用 Azure Functions,提升应用的性能和稳定性。
5. 使用 PowerShell 将 C# 控制台应用程序迁移到 Azure Functions
在某些情况下,我们可能需要将现有的 C# 控制台应用程序迁移到 Azure Functions 以利用其无服务器的优势。以下是使用 PowerShell 进行迁移的操作步骤:
准备工作
:
- 确保已经安装了 Azure PowerShell 模块。可以通过在 PowerShell 中运行
Install-Module -Name Az
来安装。
- 拥有一个 Azure 订阅,并在 Azure 门户中创建一个资源组和一个存储账户。
操作步骤
:
1.
创建 Azure Functions 项目
:
- 打开 PowerShell 并导航到要创建项目的目录。
- 运行以下命令创建一个新的 Azure Functions 项目:
func init MyFunctionProj --dotnet
- 这将创建一个名为 `MyFunctionProj` 的新的 .NET 项目。
-
导入 C# 控制台应用程序的代码 :
-
将 C# 控制台应用程序的相关代码文件复制到
MyFunctionProj项目的相应目录中。 -
确保引用的 NuGet 包也在新的项目中正确配置。可以通过在项目根目录下运行
dotnet add package <PackageName>来添加缺失的包。
-
将 C# 控制台应用程序的相关代码文件复制到
-
创建 Azure Functions 触发器 :
- 根据控制台应用程序的功能,选择合适的触发器类型(如 HTTP 触发器、定时器触发器等)。
- 例如,创建一个 HTTP 触发器:
func new --name HttpTrigger --template "HTTP trigger"
- 这将在项目中创建一个名为 `HttpTrigger` 的新的 HTTP 触发器函数。
-
修改函数代码以调用控制台应用程序逻辑
:
-
打开
HttpTrigger函数的代码文件(通常是run.csx或Function.cs)。 - 在函数中调用从控制台应用程序复制过来的代码逻辑。例如:
-
打开
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace MyFunctionProj
{
public static class HttpTrigger
{
[FunctionName("HttpTrigger")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
// 调用控制台应用程序的逻辑
// 这里假设控制台应用程序有一个名为 MyConsoleLogic 的类和一个名为 DoWork 的方法
var result = MyConsoleLogic.DoWork();
return new OkObjectResult(result);
}
}
}
-
部署到 Azure
:
- 使用以下 PowerShell 命令将项目部署到 Azure:
func azure functionapp publish <FunctionAppName>
- 其中 `<FunctionAppName>` 是你在 Azure 门户中创建的函数应用的名称。
6. 使用应用配置服务在 Azure Functions 中实现功能标志
功能标志是一种在运行时控制应用程序功能启用或禁用的技术。在 Azure Functions 中,可以使用应用配置服务来实现功能标志。
准备工作
:
- 在 Azure 门户中创建一个应用配置服务实例。
- 安装
Microsoft.FeatureManagement.AspNetCore
NuGet 包到 Azure Functions 项目中。
操作步骤
:
1.
配置应用配置服务连接
:
- 在 Azure Functions 项目的
local.settings.json
文件中添加应用配置服务的连接字符串:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AppConfigConnectionString": "<YourAppConfigConnectionString>"
}
}
- 其中 `<YourAppConfigConnectionString>` 是应用配置服务的连接字符串,可以在 Azure 门户的应用配置服务实例中获取。
-
注册功能管理服务
:
-
在
Startup.cs文件中注册功能管理服务:
-
在
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.FeatureManagement;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyFunctionProj.Startup))]
namespace MyFunctionProj
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var config = new ConfigurationBuilder()
.AddAzureAppConfiguration(Configuration.GetValue<string>("AppConfigConnectionString"))
.Build();
builder.Services.AddFeatureManagement(config);
}
}
}
-
使用功能标志
:
- 在 Azure Functions 中使用功能标志来控制功能的启用或禁用。例如:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.FeatureManagement;
namespace MyFunctionProj
{
public class MyFunction
{
private readonly IFeatureManager _featureManager;
public MyFunction(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
[FunctionName("MyFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
if (await _featureManager.IsEnabledAsync("MyFeatureFlag"))
{
// 执行启用功能的逻辑
return new OkObjectResult("My feature is enabled!");
}
else
{
// 执行禁用功能的逻辑
return new OkObjectResult("My feature is disabled.");
}
}
}
}
总结
通过以上这些最佳实践,我们可以全面提升 Azure Functions 的使用效率和应用的性能。从向队列添加多条消息、实现防御性应用、避免冷启动、共享代码,到迁移 C# 控制台应用程序和实现功能标志,每个实践都针对不同的场景和问题提供了有效的解决方案。开发者可以根据具体的需求选择合适的实践来优化自己的 Azure Functions 应用。
以下是一个总结表格,展示了各个最佳实践的主要信息:
| 最佳实践 | 主要功能 | 关键技术 |
| — | — | — |
| 使用 IAsyncCollector 函数向队列添加多条消息 | 处理客户端单个请求中的多条记录,异步创建多个队列消息 | IAsyncCollector 接口 |
| 使用 Azure 函数和队列触发器实现防御性应用 | 处理应用中的意外错误,自动将未处理消息存入毒药队列 | Azure 函数队列触发器 |
| 通过定期预热应用避免冷启动 | 解决消耗计划中的冷启动问题 | 定时器触发器和 HTTP 触发器 |
| 使用类库在 Azure 函数之间共享代码 | 重用通用库的功能 | 类库和 .dll 文件 |
| 使用 PowerShell 将 C# 控制台应用程序迁移到 Azure Functions | 将现有的 C# 控制台应用迁移到 Azure Functions | PowerShell 和 Azure Functions 工具 |
| 使用应用配置服务在 Azure Functions 中实现功能标志 | 在运行时控制应用功能的启用或禁用 | 应用配置服务和功能管理 |
以下是一个 mermaid 流程图,展示了整个 Azure Functions 最佳实践的流程:
graph LR
A[创建函数应用] --> B[添加消息到队列]
A --> C[实现防御性应用]
A --> D[避免冷启动]
A --> E[共享代码]
A --> F[迁移控制台应用]
A --> G[实现功能标志]
B --> H[使用 IAsyncCollector]
C --> I[队列触发器和毒药队列]
D --> J[定时器和 HTTP 触发器]
E --> K[类库和 .dll 文件]
F --> L[PowerShell 迁移]
G --> M[应用配置服务]
希望这些最佳实践能帮助开发者更好地利用 Azure Functions 的强大功能,构建出更高效、稳定的云原生应用。
超级会员免费看
1346

被折叠的 条评论
为什么被折叠?



