教程:使用事件订阅在 Blob 容器上触发 Azure Functions

如果将早期版本的 Blob 存储触发器与 Azure Functions 一起使用,则执行通常会延迟,因为触发器会轮询 Blob 容器的更新。 可以使用同一容器的事件订阅来触发函数以降低延迟。 事件订阅使用事件网格基础结构转发容器内发生的更改。 可以使用最新的 Azure Functions 扩展实现此功能。

本文介绍如何创建一个函数,该函数基于将 Blob 添加到容器时引发的事件运行。 你将使用 Visual Studio Code 进行本地开发,并在将项目部署到 Azure 之前检查该函数是否在本地运行。

  • 在 Azure 存储中创建常规存储 v2 帐户。
  • 在 Blob 存储中创建容器。
  • 创建事件驱动的 Blob 存储触发的函数。
  • 创建 Blob 容器的事件订阅。
  • 通过上传文件使用 ngrok 在本地进行调试。
  • 部署到 Azure 并创建经过筛选的事件订阅。

重要

本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型目前处于预览状态,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 在升级指南中详细了解 v3 和 v4 之间的差异。

先决条件

  • ngrok 实用工具,它为 Azure 提供了一种调用本地运行函数的方法。

  • Visual Studio Code 的 Azure 存储扩展,最低版本为 5.x。

注意

Visual Studio Code 的 Azure 存储扩展目前为预览版。

创建存储帐户

若要将事件订阅与 Azure 存储配合使用,需要一个常规用途 v2 存储帐户。 安装 Azure 存储扩展后,默认情况下可以从 Visual Studio Code 项目创建此存储帐户。

  1. 在 Visual Studio Code 中,打开命令面板(按 F1)并输入 Azure Storage: Create Storage Account...。 根据提示提供以下信息:

    Prompt 操作
    输入新存储帐户的名称 提供全局唯一名称。 存储帐户名称的长度必须为 3 到 24 个字符,只能包含小写字母和数字。 为方便识别,我们将对资源组和函数应用使用相同的名称。
    选择新资源的位置 为了获得更好的性能,请选择你附近的区域

    该扩展会使用你提供的名称创建一个常规用途 v2 存储帐户。 同一名称也用于包含该存储帐户的资源组。

  2. 创建存储帐户后,打开命令面板(按 F1)并输入 Azure Storage: Create Blob Container...。 根据提示提供以下信息:

    Prompt 操作
    选择资源 选择创建的存储帐户。
    输入新 blob 容器的名称 输入 samples-workitems,这是代码项目中引用的容器名称。

创建 Blob 容器后,可以创建在此容器上触发的函数和将事件传递到函数的事件订阅。

创建 Blob 触发的函数

使用 Visual Studio Code 创建 Blob 存储触发的函数时,也会创建新项目。 需要编辑该函数以使用事件订阅作为源,而不是使用常规的受轮询容器。

  1. 在 Visual Studio Code 中打开你的函数应用。

  2. 打开命令面板(按 F1),输入 Azure Functions: Create Function... 并选择“创建新项目”。

  3. 对于项目工作区,请选择目录位置。 确保为项目工作区创建一个新文件夹或选择一个空文件夹。

    不要选择已是某个工作区的一部分的项目文件夹。

  4. 根据提示提供以下信息:

    Prompt 操作
    选择一种语言 选择 C#
    选择 .NET 运行时 选择 .NET 6.0 Isolated LTS独立工作进程中运行,或选择 .NET 6.0 LTS进程内运行。
    为项目的第一个函数选择模板 选择 Azure Blob Storage trigger
    提供函数名称 输入 BlobTriggerEventGrid
    提供命名空间 输入 My.Functions
    从“local.settings.json”中选择设置 选择 Create new local app setting
    选择存储帐户 从列表中选择你创建的存储帐户。
    这是触发器将要监视的存储帐户中的路径 接受默认值 samples-workitems
    选择打开项目的方式 选择 Open in current window
    Prompt 操作
    选择一种语言 选择 Python
    选择 Python 解释器来创建虚拟环境 选择首选的 Python 解释器。 如果某个选项未显示,请输入 Python 二进制文件的完整路径。
    为项目的第一个函数选择模板 选择 Azure Blob Storage trigger
    提供函数名称 输入 BlobTriggerEventGrid
    从“local.settings.json”中选择设置 选择 Create new local app setting
    选择存储帐户 从列表中选择你创建的存储帐户。
    这是触发器将要监视的存储帐户中的路径 接受默认值 samples-workitems
    选择打开项目的方式 选择 Open in current window
    Prompt 操作
    选择一种语言 选择 Java
    选择一个 Java 版本 选择 Java 11Java 8,即在 Azure 中运行函数且已在本地验证的 Java 版本。
    提供一个组 ID 选择 com.function
    提供一个项目 ID 选择 BlobTriggerEventGrid
    提供一个版本 选择 1.0-SNAPSHOT
    提供一个包名称 选择 com.function
    提供一个应用名称 接受以 BlobTriggerEventGrid 开头的已生成名称。
    选择 Java 项目的生成工具 选择 Maven
    选择打开项目的方式 选择 Open in current window
    Prompt 操作
    选择函数项目的语言 选择 TypeScript
    选择 TypeScript 编程模型 选择 Model V4
    为项目的第一个函数选择模板 选择 Azure Blob Storage trigger
    提供函数名称 输入 BlobTriggerEventGrid
    从“local.settings.json”中选择设置 选择 Create new local app setting
    选择存储帐户 选择你创建的存储帐户。
    这是触发器将要监视的存储帐户中的路径 接受默认值 samples-workitems
    选择打开项目的方式 选择 Open in current window
    Prompt 操作
    选择函数项目的语言 选择 JavaScript
    选择 JavaScript 编程模型 选择 Model V4
    为项目的第一个函数选择模板 选择 Azure Blob Storage trigger
    提供函数名称 输入 BlobTriggerEventGrid
    从“local.settings.json”中选择设置 选择 Create new local app setting
    选择存储帐户 选择你创建的存储帐户。
    这是触发器将要监视的存储帐户中的路径 接受默认值 samples-workitems
    选择打开项目的方式 选择 Open in current window
    Prompt 操作
    选择函数项目的语言 选择 PowerShell
    为项目的第一个函数选择模板 选择 Azure Blob Storage trigger
    提供函数名称 输入 BlobTriggerEventGrid
    从“local.settings.json”中选择设置 选择 Create new local app setting
    选择存储帐户 选择你创建的存储帐户。
    这是触发器将要监视的存储帐户中的路径 接受默认值 samples-workitems
    选择打开项目的方式 选择 Open in current window
  5. 出现提示后,选择“选择存储帐户”>“添加到工作区”。

为了简化操作,本教程再次将同一存储帐户与你的函数应用配合使用。 但是,在生产环境中,可能需要为函数应用使用单独的存储帐户。 有关详细信息,请参阅 Azure Functions 的存储注意事项

升级存储扩展

若要使用基于事件网格的 Blob 存储触发器,函数至少需要存储扩展版本 5.x。

若要使用所需的扩展版本升级项目,请在终端窗口中运行以下命令:dotnet add package

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs --version 6.1.0
  1. 打开 host.json 项目文件并检查 extensionBundle 元素。

  2. 如果 extensionBundle.version 低于 3.3.0 ,请将 extensionBundle 替换为最新版本:

    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.0.0, 5.0.0)"
    }
    

更新函数以使用事件

在 BlobTriggerEventGrid.cs 文件中,将 Source = BlobTriggerSource.EventGrid 添加到 Blob 触发器属性的参数,例如:

[Function("BlobTriggerCSharp")]
public async Task Run([BlobTrigger("samples-workitems/{name}", Source = BlobTriggerSource.EventGrid, Connection = "<NAMED_STORAGE_CONNECTION>")] Stream myBlob, string name, FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("BlobTriggerCSharp");
    logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Size: {myBlob.Length} Bytes");
}

创建函数后,在 function.json 配置文件中,将 "source": "EventGrid" 添加到 myBlob 绑定,例如:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "myblob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "samples-workitems/{name}",
      "source": "EventGrid",
      "connection": "<NAMED_STORAGE_CONNECTION>"
    }
  ]
}
  1. 将生成的 Function.java 文件中,将内容替换为以下代码,并将该文件重命名为 BlobTriggerEventGrid.java

    package com.function;
    
    import com.microsoft.azure.functions.annotation.*;
    import com.microsoft.azure.functions.*;
    
    /**
    * Azure Functions with Azure Blob trigger.
    */
    public class BlobTriggerEventGrid {
        /**
        * This function will be invoked when a new or updated blob is detected at the specified path. The blob contents are provided as input to this function.
        */
        @FunctionName("BlobTriggerEventGrid")
        @StorageAccount("glengatesteventgridblob_STORAGE")
        public void run(
            @BlobTrigger(name = "content", path = "samples-workitems/{name}", dataType = "binary", source = "EventGrid" ) byte[] content,
            @BindingName("name") String name,
            final ExecutionContext context
        ) {
              context.getLogger().info("Java Blob trigger function processed a blob. Name: " + name + "\n  Size: " + content.length + " Bytes");
          }
    }
    
  2. 删除关联的单元测试文件,该文件不再适用于新的触发器类型。

创建函数后,将 source: "EventGrid" 添加到 TypeScript 文件中的 options 对象,例如:

import { app, InvocationContext } from '@azure/functions';

export async function storageBlobTrigger1(blob: Buffer, context: InvocationContext): Promise<void> {
    context.log(
        `Storage blob function processed blob "${context.triggerMetadata.name}" with size ${blob.length} bytes`
    );
}

app.storageBlob('storageBlobTrigger1', {
    path: 'samples-workitems/{name}',
    connection: 'MyStorageAccountAppSetting',
    source: 'EventGrid',
    handler: storageBlobTrigger1,
});

创建函数后,将 source: "EventGrid" 添加到 JavaScript 文件中的 options 对象,例如:

const { app } = require('@azure/functions');

app.storageBlob('storageBlobTrigger1', {
    path: 'samples-workitems/{name}',
    connection: 'MyStorageAccountAppSetting',
    source: 'EventGrid',
    handler: (blob, context) => {
        context.log(
            `Storage blob function processed blob "${context.triggerMetadata.name}" with size ${blob.length} bytes`
        );
    },
});

创建函数后,在 function.json 配置文件中,将 "source": "EventGrid" 添加到 myBlob 绑定,例如:

{
    "bindings": [
        {
            "name": "myblob",
            "type": "blobTrigger",
            "direction": "in",
            "path": "samples-workitems/{name}",
            "source": "EventGrid",
            "connection": "<NAMED_STORAGE_CONNECTION>"
        }
    ]
}

开始本地调试

你在 Azure 门户中创建事件订阅时,事件网格会验证终结点 URL。 此验证意味着,在创建可供本地调试的事件订阅之前,函数必须在本地运行,且 ngrok 实用工具启用了远程访问。 如果本地函数代码并非正在运行且可供 Azure 访问,则无法创建事件订阅。

确定 Blob 触发器终结点

在本地运行函数时,用于事件驱动的 Blob 存储触发器的默认终结点如下所示:

http://localhost:7071/runtime/webhooks/blobs?functionName=Host.Functions.BlobTriggerEventGrid
http://localhost:7071/runtime/webhooks/blobs?functionName=Host.Functions.BlobTriggerEventGrid

保存此路径,稍后将使用该路径为事件订阅创建终结点 URL。 如果对 Blob 存储触发的函数使用了不同的名称,则需要更改查询字符串中的 functionName 值。

注意

由于该终结点是为 Blob 存储触发器处理事件,因此终结点路径包括 blobs。 事件网格触发器的终结点 URL 则会在路径中包含 eventgrid

运行 ngrok

若要将断点设置到你要在计算机上调试的函数中,必须为 Azure 事件网格提供一种与本地计算机上运行的函数进行通信的方式。

ngrok 实用工具将外部请求转发到随机生成的代理服务器地址,再到本地计算机上的特定地址和端口, 以便调用计算机上运行的函数的 Webhook 终结点。

  1. 使用以下命令启动 ngrok

    ngrok.exe http http://localhost:7071
    

    该实用工具启动时,命令窗口应如以下屏幕截图所示:

    屏幕截图显示了启动“ngrok”实用程序后的命令提示符。

  2. 复制运行 ngrok 时生成的 HTTPS URL。 此值用于确定使用 ngrok 在你的计算机上公开的 Webhook 终结点。

重要

此时,不要停止 ngrok。 每次启动 ngrok 时,都会使用不同的值重新生成该 HTTPS URL。 由于事件订阅的终结点无法修改,因此你每次运行 ngrok 时都必须创建新的事件订阅。

除非创建 ngrok 帐户,否则最长 ngrok 会话时间限制为两小时。

生成终结点 URL

事件订阅中使用的终结点由三个不同的部分组成:前缀服务器名称、路径和查询字符串。 下表对这些部分进行说明:

URL 部分 说明
前缀和服务器名称 在本地运行函数时,带有 https:// 前缀的服务器名称来自 ngrok 生成的“转发”URL。 在 localhost URL 中,ngrok URL 将替换 http://localhost:7071。 在 Azure 中运行时,你将改用已发布的函数应用服务器,该服务器通常采用 https://<FUNCTION_APP_NAME>.chinacloudsites.cn 形式。
路径 终结点 URL 的路径部分来自前面复制的 localhost URL,对于 Blob 存储触发器,该路径部分类似于 /runtime/webhooks/blobs。 对于事件网格触发器,该路径将是 /runtime/webhooks/EventGrid
查询字符串 对于包括 .NET Isolated 在内的所有语言,functionName=Host.Functions.BlobTriggerEventGrid 参数(.NET In-process 除外,它在查询字符串中应为 functionName=BlobTriggerEventGrid)会设置处理事件的函数的名称。 如果你对你的函数使用了其他名称,则需要更改此值。 在本地运行时,不需要访问密钥。 在 Azure 中运行时,还需要在 URL 中包含一个 code= 参数,该参数包含可从门户获取的密钥。

下面的屏幕截图显示了一个示例,说明了使用名为 BlobTriggerEventGrid 的 Blob 存储触发器类型时最终终结点 URL 应是怎样的:

终结点选择

开始调试

在 ngrok 已处于运行状态时,按下面所示启动本地项目:

  1. 在处理日志记录的行的函数中设置断点。

  2. 启动调试会话。

    打开新终端并运行以下 mvn 命令以启动调试会话。

    mvn azure-functions:run -DenableDebug
    

    按 F5 启动调试会话。

如果代码正在运行且 ngrok 正在转发请求,便可以创建 Blob 容器的事件订阅了。

创建事件订阅

由 Azure 事件网格提供支持的事件订阅会根据链接 Blob 容器中的更改引发事件。 然后,此事件将发送到函数触发器上的 Webhook 终结点。 创建事件订阅后,终结点 URL 将无法更改。 这意味着,完成本地调试(或者重新启动了 ngrok)后,将需要删除并重新创建事件订阅。

  1. 在 Visual Studio Code 中,选择“活动”栏中的 Azure 图标。 在“资源”中,展开订阅,然后展开“存储帐户”,右键单击之前创建的存储帐户,然后选择“在门户中打开”。

  2. 登录到 Azure 门户并记下存储帐户的资源组。 你将在同一组中创建其他资源,以便在完成后更轻松地清理资源。

  3. 从左侧菜单中选择“事件”选项。

    添加存储帐户事件

  4. 在“事件”窗口中,选择“+ 事件订阅”按钮,并将下表中的值提供到“基本信息”选项卡中:

    设置 建议值 说明
    名称 myBlobLocalNgrokEventSub 用于标识事件订阅的名称。 可以使用该名称快速查找事件订阅。
    事件架构 事件网格架构 对事件使用默认架构。
    系统主题名称 samples-workitems-blobs 表示容器的主题的名称。 该主题是随第一个订阅创建的,你将对未来的事件订阅使用该主题。
    筛选事件类型 已创建 Blob
    终结点类型 Webhook 该 Blob 存储触发器使用 Webhook 终结点。 你将对事件网格触发器使用 Azure Functions。
    终结点 基于 ngrok 的 URL 终结点 使用前面确定的基于 ngrok 的 URL 终结点。
  5. 选择“确认选择”以验证终结点 URL。

  6. 选择“创建”以创建事件订阅。

将文件上传到容器

现在,事件订阅已到位并且你的代码项目和 ngrok 仍在运行,你便可以将文件上传到存储容器以触发函数。 可以使用 Visual Studio Code 将文件从计算机上传到 Blob 存储容器。

  1. 在 Visual Studio Code 中,打开命令面板(按 F1)并键入 Azure Storage: Upload Files...

  2. 在“打开”对话框中,选择一个文件(最好是一个不太大的二进制映像文件),然后选择“上传”。

  3. 根据提示提供以下信息:

    设置 建议值 说明
    选择资源 存储帐户名称 选择在上一步中创建的存储帐户的名称。
    选择资源类型 Blob 容器 将会上传到 Blob 容器。
    选择 Blob 容器 samples-workitems 此值是上一步中创建的容器的名称。
    输入此上传的目标目录 默认值 只需接受默认值 /,即容器根目录。

此命令将文件从计算机上传到 Azure 中的存储容器。 此时,正在运行的 ngrok 实例应报告一个请求已转发。 在调试会话的 func.exe 输出中,也可看到你的函数已启动。 此时,调试会话正在你设置断点的位置等待。

将项目发布到 Azure

现在已在本地成功验证函数代码,是时候将项目发布到 Azure 中的新函数应用了。

创建函数应用

以下步骤创建 Azure 中所需的资源并部署项目文件。

  1. 在命令面板中,输入“Azure Functions: 在 Azure 中创建函数应用...(高级)”。

  2. 按提示操作并提供以下信息:

    Prompt 选择
    输入新的函数应用的全局唯一名称。 键入用于标识新函数应用的全局唯一名称,然后按 Enter。 函数应用名称的有效字符包括 a-z0-9-。 写下此名称;稍后在构建新的终结点 URL 时将需要它。
    选择一个运行时堆栈。 选择你一直在本地运行的语言版本。
    选择 OS。 选择“Linux”或“Windows”。 Python 应用必须在 Linux 上运行。
    选择新资源的资源组。 选择你使用存储帐户创建的资源组的名称,之前你在门户中时记下了该资源组名称。
    选择新资源的位置。 在与你靠近或者与函数要访问的其他服务靠近的区域中选择一个位置。
    选择托管计划。 为无服务器消耗计划托管选择“消耗”,这样,仅当函数运行时你才需要付费。
    选择一个存储帐户。 选择已在使用的现有存储帐户的名称。
    为你的应用选择 Application Insights 资源。 选择“创建新的 Application Insights 资源”,然后根据提示键入用于存储函数运行时数据的实例的名称。

    创建函数应用并应用了部署包之后,会显示一个通知。 在此通知中选择“查看输出”以查看创建和部署结果,其中包括你创建的 Azure 资源。

部署函数代码

重要

部署到现有函数应用将始终覆盖该应用在 Azure 中的内容。

  1. 在活动栏中选择 Azure 图标,然后在“工作区”区域中选择你的项目文件夹,并选择“部署...”按钮。

    从 Visual Studio Code 工作区部署项目

  2. 选择“部署到函数应用...”,然后选择刚刚创建的函数应用,选择“部署”。

  3. 在部署完成后,选择“查看输出”以查看创建和部署结果,其中包括你创建的 Azure 资源。 如果错过了通知,请选择右下角的响铃图标以再次查看。

    “查看输出”窗口的屏幕截图。

发布应用程序设置

由于 local.settings.json 中的本地设置不会自动发布,因此现在必须上传这些设置,以便函数在 Azure 中正常运行。

在命令面板中,输入“Azure Functions: 上传本地设置...”,然后在“选择资源。”提示下选择函数应用的名称。

重新创建事件订阅

现在函数应用已在 Azure 中运行,你需要创建新的事件订阅。 这个新的事件订阅使用 Azure 中函数的终结点。 还需向事件订阅添加筛选器,以便仅在 JPEG (.jpg) 文件添加到容器时才触发该函数。 在 Azure 中,终结点 URL 还包含访问密钥,这有助于阻止事件网格以外的执行组件访问该终结点。

获取 Blob 扩展密钥

  1. 在 Visual Studio Code 中,选择“活动”栏中的 Azure 图标。 在“资源”中,展开你的订阅,展开“函数应用”,右键单击你创建的函数应用,然后选择“在门户中打开”。

  2. 在左侧菜单中的“函数”下,选择“应用密钥”。

  3. 在“系统密钥”下,选择名为“blobs_extension”的密钥,并复制密钥值。

需将此值包含在新终结点 URL 的查询字符串中。

生成终结点 URL

根据以下示例,为 Blob 存储触发器创建新的终结点 URL:

https://<FUNCTION_APP_NAME>.chinacloudsites.cn/runtime/webhooks/blobs?functionName=Host.Functions.BlobTriggerEventGrid&code=<BLOB_EXTENSION_KEY>
https://<FUNCTION_APP_NAME>.chinacloudsites.cn/runtime/webhooks/blobs?functionName=Host.Functions.BlobTriggerEventGrid&code=<BLOB_EXTENSION_KEY>

在此示例中,将 <FUNCTION_APP_NAME> 替换为你的函数应用的名称,并将 <BLOB_EXTENSION_KEY> 替换为你从门户获得的值。 如果对函数使用了不同的名称,则还要根据需要更改 functionName 查询字符串。

创建经过筛选的事件订阅

由于无法更改事件订阅的终结点 URL,因此必须创建新的事件订阅。 此时还应删除旧的事件订阅,因为它不能重复使用。

这一次,需要包含有关事件订阅的筛选器,以便只有 JPEG 文件 (*.jpg) 才触发函数。

  1. 在 Visual Studio Code 中,选择“活动”栏中的 Azure 图标。 在“资源”中,展开订阅,然后展开“存储帐户”,右键单击之前创建的存储帐户,然后选择“在门户中打开”。

  2. Azure 门户的左侧菜单中选择“事件”选项。

  3. 在“事件”窗口中,选择基于 ngrok 的旧事件订阅,然后选择“删除”>“保存”。 此操作将删除旧事件订阅。

  4. 选择“+ 事件订阅”按钮,并将下表中的值提供到“基本信息”选项卡中:

    设置 建议值 说明
    名称 myBlobAzureEventSub 用于标识事件订阅的名称。 可以使用该名称快速查找事件订阅。
    事件架构 事件网格架构 对事件使用默认架构。
    筛选事件类型 已创建 Blob
    终结点类型 Webhook 该 Blob 存储触发器使用 Webhook 终结点。 你将对事件网格触发器使用 Azure Functions。
    终结点 基于 Azure 的新 URL 终结点 使用你生成的 URL 终结点,其中包括密钥值。
  5. 选择“确认选择”以验证终结点 URL。

  6. 选择“筛选器”选项卡,在“主题筛选器”下选中“启用主题筛选”,在“主题结尾为”中键入 .jpg。 这会将事件筛选为仅限 JPEG 文件。

    添加筛选器

  7. 选择“创建”以创建事件订阅。

在 Azure 中验证函数

现在整个拓扑都在运行 Azure,是时候验证一切是否正常工作了。 由于你已经在门户中,因此最简单的方法是从那里上传文件。

  1. 在门户内的存储帐户页中,选择“容器”,然后选择 samples-workitems 容器。

  2. 选择“上传”按钮以打开右侧的上传页面,浏览本地文件系统以查找要上传的 .jpg 文件,然后选择“上传”按钮以上传 Blob。 现在,可以验证函数是否已基于容器上传事件运行。

  3. 在存储帐户中,返回到“事件”页,选择“事件订阅”,应会看到已传递一个事件。

  4. 返回门户中的函数应用页,在“函数”下选择“函数”,选择你的函数,应会看到至少为 1 的“总执行次数”。

  5. 在“开发人员”下,选择“监视”,应会看到从成功的函数执行中写入的跟踪。 由于事件由 Application Insights 处理,因此可能会有五分钟的延迟。

清理资源

若要继续执行下一步骤将 Azure 存储队列绑定添加到函数,需要保留到目前为止构建的所有资源。

否则,可以使用以下步骤删除函数应用及其相关资源,以免产生任何额外的费用。

  1. 在 Visual Studio Code 中,按 F1 打开命令面板。 在命令面板中,搜索并选择 Azure: Open in portal

  2. 选择你的函数应用,然后按 Enter。 随即将在 Azure 门户中打开函数应用页面。

  3. 在“概览”选项卡中,选择“资源组”旁边的命名链接。

    从函数应用页选择要删除的资源组的屏幕截图。

  4. 在“资源组”页上查看所包括的资源的列表,然后验证这些资源是否是要删除的。

  5. 选择“删除资源组”,然后按说明操作。

    可能需要数分钟才能删除完毕。 完成后会显示一个通知,持续数秒。 也可以选择页面顶部的钟形图标来查看通知。

有关 Functions 成本的详细信息,请参阅估算消耗计划成本

后续步骤