教程:Azure Cache for Redis 中的 Azure Functions 触发器和绑定入门

本教程介绍了如何使用 Azure Cache for Redis 和 Azure Functions 实施基本触发器。 它指导你完成使用 Visual Studio Code (VS Code) 采用 C# 编写和部署 Azure 函数。

在本教程中,你将了解如何执行以下操作:

  • 设置所需的工具。
  • 配置并连接到缓存。
  • 创建 Azure 函数并向其部署代码。
  • 确认触发器的日志记录。

先决条件

设置 Azure Cache for Redis 实例

使用 Azure 门户或首选 CLI 工具创建新的 Azure Cache for Redis 实例。 本教程使用标准 C1 实例,这是一个很好的起点。 使用快速入门指南来开始使用。

在 Azure 门户中创建缓存的屏幕截图。

默认设置应已足够。 本教程使用公共终结点进行演示,但我们建议对生产中的任何内容使用专用终结点。

创建缓存可能需要几分钟时间。 可以在该过程完成时转到下一部分。

设置 Visual Studio Code

  1. 如果尚未安装 VS Code 的 Azure Functions 扩展,请在“扩展”菜单中搜索“Azure Functions”,然后选择“安装”。 如果尚未安装 C# 扩展,也请安装它。

    在 VS Code 中安装的所需扩展的截图。

  2. 转到“Azure”选项卡。请登录到你的 Azure 帐户。

  3. 要存储你正在构建的项目,请在计算机上创建一个新的本地文件夹。 本教程使用 RedisAzureFunctionDemo 作为示例。

  4. 在“Azure”选项卡上,通过选择“工作区”选项卡右上角的闪电图标来创建新的函数应用。

  5. 选择“创建函数...”

    屏幕截图显示了从 VS Code 添加新函数的图标。

  6. 选择已创建的文件夹,以开始创建新的 Azure Functions 项目。 屏幕上将会显示多个提示。 选择:

    • C# 作为语言。
    • .NET 8.0 独立 LTS 作为 .NET 运行时。
    • 以“暂时跳过”作为项目模板。

    如果未安装 .NET Core SDK,则系统会提示你安装此项。

    重要

    对于 .NET 函数,建议在进程内模型中使用独立辅助角色模型。 有关进程内和独立工作器模型的比较,请参阅 Azure Functions 上 .NET 的独立工作器模型与进程内模型之间的差异。 此示例使用独立工作器模型

  7. 确认新项目显示在“资源管理器”窗格中。

    VS Code 中工作区的屏幕截图。

安装必要的 NuGet 包

需要安装 Microsoft.Azure.Functions.Worker.Extensions.Redis,它是用于 Redis 扩展的 NuGet 包,允许将 Redis 密钥空间通知用作 Azure Functions 中的触发器。

通过转到 VS Code 中的“终端”选项卡,并输入以下命令来安装此包:

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Redis --prerelease

注意

Microsoft.Azure.Functions.Worker.Extensions.Redis 包用于 .NET 独立工作进程函数。 .NET 进程内函数和所有其他语言将改用 Microsoft.Azure.WebJobs.Extensions.Redis 包。

配置缓存

  1. 转到新创建的 Azure Cache for Redis 实例。

  2. 转到 Azure 门户中你的缓存,然后:

    1. 在“资源”菜单上,选择“高级设置”。

    2. 向下滚动到“notify-keyspace-events”框,然后输入 KEA

      KEA”是一个配置字符串,它为所有键和事件启用键空间通知。 有关键空间配置字符串的详细信息,请参阅 Redis 文档

    3. 在窗口顶部选择“保存”。

    门户中 Azure Cache for Redis 高级设置的屏幕截图。

  3. 在“资源”菜单上找到“访问密钥”,然后记下或复制“主要连接字符串”框的内容。 此字符串用于连接到缓存。

    屏幕截图显示访问密钥的主要连接字符串。

设置 Redis 触发器的示例代码

  1. 在 VS Code 中,将名为 Common.cs 的文件添加到项目中。 此类用于帮助分析 PubSubTrigger 的 JSON 序列化响应。

  2. 将以下代码复制粘贴到 Common.cs 文件中:

    public class Common
    {
        public const string connectionString = "redisConnectionString";
    
        public class ChannelMessage
        {
            public string SubscriptionChannel { get; set; }
            public string Channel { get; set; }
            public string Message { get; set; }
        }
    }
    
  3. 将名为 RedisTriggers.cs 的文件添加到项目。

  4. 将以下代码示例复制并粘贴到新文件中:

    using Microsoft.Extensions.Logging;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.Functions.Worker.Extensions.Redis;
    
    public class RedisTriggers
    {
        private readonly ILogger<RedisTriggers> logger;
    
        public RedisTriggers(ILogger<RedisTriggers> logger)
        {
            this.logger = logger;
        }
    
        // PubSubTrigger function listens to messages from the 'pubsubTest' channel.
        [Function("PubSubTrigger")]
        public void PubSub(
        [RedisPubSubTrigger(Common.connectionString, "pubsubTest")] Common.ChannelMessage channelMessage)
        {
        logger.LogInformation($"Function triggered on pub/sub message '{channelMessage.Message}' from channel '{channelMessage.Channel}'.");
        }
    
        // KeyeventTrigger function listens to key events from the 'del' operation.
        [Function("KeyeventTrigger")]
        public void Keyevent(
            [RedisPubSubTrigger(Common.connectionString, "__keyevent@0__:del")] Common.ChannelMessage channelMessage)
        {
            logger.LogInformation($"Key '{channelMessage.Message}' deleted.");
        }
    
        // KeyspaceTrigger function listens to key events on the 'keyspaceTest' key.
        [Function("KeyspaceTrigger")]
        public void Keyspace(
            [RedisPubSubTrigger(Common.connectionString, "__keyspace@0__:keyspaceTest")] Common.ChannelMessage channelMessage)
        {
            logger.LogInformation($"Key 'keyspaceTest' was updated with operation '{channelMessage.Message}'");
        }
    
        // ListTrigger function listens to changes to the 'listTest' list.
        [Function("ListTrigger")]
        public void List(
            [RedisListTrigger(Common.connectionString, "listTest")] string response)
        {
            logger.LogInformation(response);
        }
    
        // StreamTrigger function listens to changes to the 'streamTest' stream.
        [Function("StreamTrigger")]
        public void Stream(
            [RedisStreamTrigger(Common.connectionString, "streamTest")] string response)
        {
            logger.LogInformation(response);
        }
    }
    
  5. 本教程介绍了在 Redis 活动上触发的多种方法:

    • PubSubTrigger,这会在将活动发布到名为 pubsubTest 的发布/订阅通道时触发。
    • KeyspaceTrigger,它是基于 pub/sub 触发器构建的。 可使用它来查找对 keyspaceTest 键的更改。
    • KeyeventTrigger,这也是基于 Pub/Sub 触发器构建的。 可使用它可以查找对 DEL 命令的任何使用。
    • ListTrigger,用于查找对 listTest 列表进行的更改。
    • StreamTrigger,用于查找对 streamTest 流进行的更改。

连接到缓存

  1. 若要在 Redis 活动上触发,需要传入缓存实例的连接字符串。 此信息存储在你的文件夹中自动创建的 local.settings.json 文件中。 建议将本地设置文件用作安全最佳做法。

  2. 若要连接到缓存,请在 local.settings.json 文件中添加 ConnectionStrings 部分,然后使用 redisConnectionString 参数添加连接字符串。 该部分应如下例所示:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
        "redisConnectionString": "<your-connection-string>"
      }
    }
    

    Common.cs 中的代码会在本地运行时查看该值:

    public const string connectionString = "redisConnectionString";
    

在本地生成并运行代码

  1. 在 VS Code 中切换到“运行和调试”选项卡,然后选择绿色箭头以在本地调试代码。 如果未安装 Azure Functions 核心工具,系统将会提示你安装该工具。 在这种情况下,需要在安装后重启 VS Code。

  2. 代码应成功生成。 可以在终端输出中跟踪其进度。

  3. 要测试触发器功能,请尝试创建和删除 keyspaceTest 键。

    可以使用喜欢的任何方式连接到缓存。 一种简单的方法是使用 Azure Cache for Redis 门户中的内置控制台工具。 在 Azure 门户中转到缓存实例,然后选择“控制台”以将其打开。

    C-Sharp 代码和连接字符串的屏幕截图。

    打开控制台后,请尝试以下命令:

    • SET keyspaceTest 1
    • SET keyspaceTest 2
    • DEL keyspaceTest
    • PUBLISH pubsubTest testMessage
    • LPUSH listTest test
    • XADD streamTest * name Clippy

    控制台以及一些 Redis 命令和结果的屏幕截图。

  4. 确认触发器正在终端中激活。

    VS Code 编辑器的屏幕截图,其中代码正在运行。

添加 Redis 绑定

绑定增加了一种简化的方法来读取或写入存储在 Redis 实例上的数据。 为了展示绑定的好处,我们添加了另外两个函数。 一个叫做 SetGetter,它在每次设置键时都会触发,并使用输入绑定返回键的新值。 另一个叫做 StreamSetter,它在新项添加到流 myStream 时触发,并使用输出绑定将值 true 写入键 newStreamEntry

  1. 将名为 RedisBindings.cs 的文件添加到项目中。

  2. 将以下代码示例复制并粘贴到新文件中:

    using Microsoft.Extensions.Logging;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.Functions.Worker.Extensions.Redis;
    
    public class RedisBindings
    {
        private readonly ILogger<RedisBindings> logger;
    
        public RedisBindings(ILogger<RedisBindings> logger)
        {
            this.logger = logger;
        }
    
        //This example uses the PubSub trigger to listen to key events on the 'set' operation. A Redis Input binding is used to get the value of the key being set.
        [Function("SetGetter")]
        public void SetGetter(
            [RedisPubSubTrigger(Common.connectionString, "__keyevent@0__:set")] Common.ChannelMessage channelMessage,
            [RedisInput(Common.connectionString, "GET {Message}")] string value)
        {
            logger.LogInformation($"Key '{channelMessage.Message}' was set to value '{value}'");
        }
    
        //This example uses the PubSub trigger to listen to key events to the key 'key1'. When key1 is modified, a Redis Output binding is used to set the value of the 'key1modified' key to 'true'.
        [Function("SetSetter")]
        [RedisOutput(Common.connectionString, "SET")]
        public string SetSetter(
            [RedisPubSubTrigger(Common.connectionString, "__keyspace@0__:key1")] Common.ChannelMessage channelMessage)
        {
            logger.LogInformation($"Key '{channelMessage.Message}' was updated. Setting the value of 'key1modified' to 'true'");
            return $"key1modified true";
        }
    }
    
  3. 在 VS Code 中切换到“运行和调试”选项卡,然后选择绿色箭头以在本地调试代码。 代码应成功生成。 可以在终端输出中跟踪其进度。

  4. 若要测试输入绑定功能,请尝试为任何键设置新值,例如使用命令 SET hello world。你应看到 SetGetter 函数触发并返回更新的值。

  5. 若要测试输出绑定功能,请尝试使用命令 XADD myStream * item Order1 向流 myStream 添加新项。 请注意,StreamSetter 函数在新流条目上触发,并将值 true 设置为另一个名为 newStreamEntry 的键。 该 set 命令还会触发 SetGetter 函数。

将代码部署到 Azure 函数

  1. 创建新的 Azure 函数:

    1. 返回“Azure”选项卡并展开订阅。

    2. 右键单击“函数应用”,然后选择“在 Azure 中创建函数应用(高级)”。

    在 VS Code 中创建函数应用的选择屏幕截图。

  2. 你将获得有关配置新函数应用的信息的多个提示:

    • 输入唯一名称。
    • 选择“.NET 8 独立”作为运行时堆栈。
    • 选择“Linux”或“Windows”(两者均可)。
    • 选择现有或新的资源组来保留函数应用。
    • 选择与缓存实例相同的区域。
    • 选择“高级”作为托管计划。
    • 创建新的 Azure 应用服务计划。
    • 选择“EP1”定价层。
    • 选择现有存储帐户,或者新建存储帐户。
    • 新建 Application Insights 资源。 使用该资源确认触发器是否工作正常。

    重要

    消耗函数当前不支持 Redis 触发器。

  3. 等待几分钟,以便创建新的函数应用。 它会显示在订阅中的“函数应用”下。 右键单击新的函数应用,然后选择“部署到函数应用”。

    在 VS Code 中部署到函数应用的选择屏幕截图。

  4. 应用将会生成并开始部署。 可在输出窗口中跟踪其进度。

添加连接字符串信息

  1. 在 Azure 门户中,转到新的函数应用,然后从资源菜单中选择“环境变量”。

  2. 在工作窗格中,转到“应用设置”。

  3. 对于“名称”,输入 redisConnectionString

  4. 对于“”,输入你的连接字符串。

  5. 在页面上选择“应用”以确认。

  6. 导航到“概览”窗格,然后选择“重启”以使用连接字符串信息重新启动函数应用。

测试触发器和绑定

  1. 完成部署并添加连接字符串信息后,在 Azure 门户中打开函数应用。 然后从资源菜单中选择“日志流”。

  2. 等待 Log Analytics 连接,然后使用 Redis 控制台激活任何触发器。 确认此处记录了触发器。

    资源菜单中函数应用资源的日志流的屏幕截图。

清理资源

要继续使用在本文中创建的资源,请保留资源组。

否则,为了避免与资源相关的费用,若已用完资源,可以删除已创建的 Azure 资源组。

警告

删除资源组的操作不可逆。 删除一个资源组时,该资源组中的所有资源都会被永久删除。 请确保不会意外删除错误的资源组或资源。 如果在现有资源组内创建了资源,并且该资源组中还有想要保留的资源,可以逐个删除这些资源,而不是删除资源组。

删除资源组

  1. 登录到 Azure 门户,然后选择“资源组”。

  2. 选择要删除的资源组。

    如果有多个资源组,请在“筛选任何字段”中,输入为完成本文创建的资源组的名称。 在搜索结果列表中,选择该资源组。

    屏幕截图显示了可从中选择要删除的资源组列表。

  3. 选择“删除资源组”

  4. 在“删除资源组”窗格中,输入资源组的名称进行确认,然后选择“删除”。

    屏幕截图显示了要求输入资源名称以确认删除的框。

很快将会删除该资源组及其所有资源。