使用命令行工具将 Azure Functions 连接到 Azure 存储Connect Azure Functions to Azure Storage using command line tools

本文介绍如何将 Azure 存储队列与在前一篇快速入门中创建的函数和存储帐户相集成。In this article, you integrate an Azure Storage queue with the function and storage account you created in the previous quickstart article. 可以使用一个输出绑定来实现这种集成。该绑定可将 HTTP 请求中的数据写入队列中的消息。 You achieve this integration by using an output binding that writes data from an HTTP request to a message in the queue. 除了在前一篇快速入门中提到的几美分费用以外,完成本文不会产生其他费用。Completing this article incurs no additional costs beyond the few USD cents of the previous quickstart. 有关绑定的详细信息,请参阅 Azure Functions 触发器和绑定的概念To learn more about bindings, see Azure Functions triggers and bindings concepts.

配置本地环境Configure your local environment

在开始之前,必须完成文章快速入门:从命令行创建 Azure Functions 项目Before you begin, you must complete the article, Quickstart: Create an Azure Functions project from the command line. 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。If you already cleaned up resources at the end of that article, go through the steps again to recreate the function app and related resources in Azure.

在开始之前,必须完成文章快速入门:从命令行创建 Azure Functions 项目Before you begin, you must complete the article, Quickstart: Create an Azure Functions project from the command line. 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。If you already cleaned up resources at the end of that article, go through the steps again to recreate the function app and related resources in Azure.

在开始之前,必须完成文章快速入门:从命令行创建 Azure Functions 项目Before you begin, you must complete the article, Quickstart: Create an Azure Functions project from the command line. 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。If you already cleaned up resources at the end of that article, go through the steps again to recreate the function app and related resources in Azure.

在开始之前,必须完成文章快速入门:从命令行创建 Azure Functions 项目Before you begin, you must complete the article, Quickstart: Create an Azure Functions project from the command line. 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。If you already cleaned up resources at the end of that article, go through the steps again to recreate the function app and related resources in Azure.

在开始之前,必须完成文章快速入门:从命令行创建 Azure Functions 项目Before you begin, you must complete the article, Quickstart: Create an Azure Functions project from the command line. 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。If you already cleaned up resources at the end of that article, go through the steps again to recreate the function app and related resources in Azure.

检索 Azure 存储连接字符串Retrieve the Azure Storage connection string

前面你已创建一个供函数应用使用的 Azure 存储帐户。Earlier, you created an Azure Storage account for use by the function app. 此帐户的连接字符串安全存储在 Azure 中的应用设置内。The connection string for this account is stored securely in app settings in Azure. 将设置下载到 local.settings.json 文件中后,在本地运行函数时,可以在同一帐户中使用该连接写入存储队列。By downloading the setting into the local.settings.json file, you can use that connection write to a Storage queue in the same account when running the function locally.

  1. 在项目的根目录中运行以下命令(请将 <app_name> 替换为前一篇快速入门中所用的函数应用名称)。From the root of the project, run the following command, replacing <app_name> with the name of your function app from the previous quickstart. 此命令将覆盖该文件中的任何现有值。This command will overwrite any existing values in the file.

    func azure functionapp fetch-app-settings <app_name>
    
  2. 打开 local.settings.json,找到名为 AzureWebJobsStorage 的值,即存储帐户连接字符串。Open local.settings.json and locate the value named AzureWebJobsStorage, which is the Storage account connection string. 在本文的其他部分,将使用名称 AzureWebJobsStorage 和该连接字符串。You use the name AzureWebJobsStorage and the connection string in other sections of this article.

重要

由于 local.settings.json 包含从 Azure 下载的机密,因此请始终从源代码管理中排除此文件。Because local.settings.json contains secrets downloaded from Azure, always exclude this file from source control. 连同本地函数项目一起创建的 .gitignore 文件默认会排除该文件。The .gitignore file created with a local functions project excludes the file by default.

注册绑定扩展Register binding extensions

除了 HTTP 和计时器触发器,绑定将实现为扩展包。With the exception of HTTP and timer triggers, bindings are implemented as extension packages. 在终端窗口中运行以下 dotnet add package 命令,将存储扩展包添加到项目中。Run the following dotnet add package command in the Terminal window to add the Storage extension package to your project.

dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage --version 3.0.4

现在,你可以将存储输出绑定添加到项目。Now, you can add the storage output binding to your project.

将输出绑定定义添加到函数Add an output binding definition to the function

尽管一个函数只能有一个触发器,但它可以有多个输入和输出绑定,因此,你无需编写自定义集成代码,就能连接到其他 Azure 服务和资源。Although a function can have only one trigger, it can have multiple input and output bindings, which let you connect to other Azure services and resources without writing custom integration code.

在函数文件夹中的 function.json 文件内声明这些绑定。You declare these bindings in the function.json file in your function folder. 在前一篇快速入门中,HttpExample 文件夹中的 function.json 文件在 bindings 集合中包含两个绑定:From the previous quickstart, your function.json file in the HttpExample folder contains two bindings in the bindings collection:

    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req",
            "methods": [
                "get",
                "post"
            ]
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]

每个绑定至少有一个类型、一个方向和一个名称。Each binding has at least a type, a direction, and a name. 在以上示例中,第一个绑定的类型为 httpTrigger,方向为 inIn the example above, the first binding is of type httpTrigger with the direction in. 对于 in 方向,name 指定在触发器调用函数时,要发送到该函数的输入参数的名称。For the in direction, name specifies the name of an input parameter that's sent to the function when invoked by the trigger.

集合中的第二个绑定名为 resThe second binding in the collection is named res. http 绑定是用于写入 HTTP 响应的输出绑定 (out)。This http binding is an output binding (out) that is used to write the HTTP response.

若要从此函数写入 Azure 存储队列,请添加类型为 queue、名称为 msgout 绑定,如以下代码所示:To write to an Azure Storage queue from this function, add an out binding of type queue with the name msg, as shown in the code below:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

::: zone-end

集合中的第二个绑定名为 resThe second binding in the collection is named res. http 绑定是用于写入 HTTP 响应的输出绑定 (out)。This http binding is an output binding (out) that is used to write the HTTP response.

若要从此函数写入 Azure 存储队列,请添加类型为 queue、名称为 msgout 绑定,如以下代码所示:To write to an Azure Storage queue from this function, add an out binding of type queue with the name msg, as shown in the code below:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

在这种情况下,msg 将作为输出参数提供给函数。In this case, msg is given to the function as an output argument. 对于 queue 类型,还必须在 queueName 中指定队列的名称,并在 connection 中提供 Azure 存储连接的名称(来自 local.settings.json)。 For a queue type, you must also specify the name of the queue in queueName and provide the name of the Azure Storage connection (from local.settings.json) in connection.

在 C# 类库项目中,绑定被定义为函数方法上的绑定属性。In a C# class library project, the bindings are defined as binding attributes on the function method. 然后,基于这些属性自动生成 Functions 所需的 function.json 文件。The function.json file required by Functions is then auto-generated based on these attributes.

打开 HttpExample.cs 项目文件,并将以下参数添加到 Run 方法定义中:Open the HttpExample.cs project file and add the following parameter to the Run method definition:

[Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg,

msg 参数为 ICollector<T> 类型,表示函数完成时写入输出绑定的消息集合。The msg parameter is an ICollector<T> type, which represents a collection of messages that are written to an output binding when the function completes. 在这种情况下,输出是名为的 outqueue 存储队列。In this case, the output is a storage queue named outqueue. 存储帐户的连接字符串由 StorageAccountAttribute 设置。The connection string for the Storage account is set by the StorageAccountAttribute. 此属性指示包含存储帐户连接字符串的设置,可以在类、方法或参数级别应用。This attribute indicates the setting that contains the Storage account connection string and can be applied at the class, method, or parameter level. 在这种情况下,可以省略 StorageAccountAttribute,因为你已使用默认存储帐户。In this case, you could omit StorageAccountAttribute because you are already using the default storage account.

Run 方法定义如下所示:The Run method definition should now look like the following:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)

在 Java 项目中,绑定被定义为函数方法上的绑定注释。In a Java project, the bindings are defined as binding annotations on the function method. 然后根据这些注释自动生成 function.json 文件。The function.json file is then autogenerated based on these annotations.

浏览到函数代码在 src/main/java 下的位置,打开 Function.java 项目文件,然后将以下参数添加到 run 方法定义:Browse to the location of your function code under src/main/java, open the Function.java project file, and add the following parameter to the run method definition:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

msg 参数为 OutputBinding<T> 类型,表示函数完成时作为消息写入到输出绑定的字符串集合。The msg parameter is an OutputBinding<T> type, which represents a collection of strings that are written as messages to an output binding when the function completes. 在这种情况下,输出是名为的 outqueue 存储队列。In this case, the output is a storage queue named outqueue. 存储帐户的连接字符串由 connection 方法设置。The connection string for the Storage account is set by the connection method. 请传递包含存储帐户连接字符串的应用程序设置,而不是传递连接字符串本身。Rather than the connection string itself, you pass the application setting that contains the Storage account connection string.

run 方法定义现在应如以下示例所示:The run method definition should now look like the following example:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

有关绑定的详细信息,请参阅 Azure Functions 触发器和绑定的概念队列输出配置For more information on the details of bindings, see Azure Functions triggers and bindings concepts and queue output configuration.

添加使用输出绑定的代码Add code to use the output binding

定义队列绑定后,现在可以更新函数,以接收 msg 输出参数并将消息写入队列。With the queue binding defined, you can now update your function to receive the msg output parameter and write messages to the queue.

添加在 context.bindings 上使用 msg 输出绑定对象来创建队列消息的代码。Add code that uses the msg output binding object on context.bindings to create a queue message. 请在 context.res 语句之前添加此代码。Add this code before the context.res statement.

// Add a message to the Storage queue.
context.bindings.msg = "Name passed to the function: " + 
(req.query.name || req.body.name);

此时,你的函数应如下所示:At this point, your function should look as follows:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue.
        context.bindings.msg = "Name passed to the function: " + 
        (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

添加在 context.bindings 上使用 msg 输出绑定对象来创建队列消息的代码。Add code that uses the msg output binding object on context.bindings to create a queue message. 请在 context.res 语句之前添加此代码。Add this code before the context.res statement.

context.bindings.msg = name;

此时,你的函数应如下所示:At this point, your function should look as follows:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

添加使用 Push-OutputBinding cmdlet 通过 msg 输出绑定将文本写入队列的代码。Add code that uses the Push-OutputBinding cmdlet to write text to the queue using the msg output binding. if 语句中设置“正常”状态之前,请添加此代码。Add this code before you set the OK status in the if statement.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

此时,你的函数应如下所示:At this point, your function should look as follows:

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    # Write the $name value to the queue, 
    # which is the name passed to the function.
    $outputMsg = $name
    Push-OutputBinding -name msg -Value $outputMsg

    $status = [HttpStatusCode]::OK
    $body = "Hello $name"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

添加使用 msg 输出绑定对象来创建队列消息的代码。Add code that uses the msg output binding object to create a queue message. 请在方法返回之前添加此代码。Add this code before the method returns.

if (!string.IsNullOrEmpty(name))
{
    // Add a message to the output collection.
    msg.Add(string.Format("Name passed to the function: {0}", name));
}

此时,你的函数应如下所示:At this point, your function should look as follows:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a message to the output collection.
        msg.Add(string.Format("Name passed to the function: {0}", name));
    }
    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

现在可以使用新的 msg 参数,从函数代码写入到输出绑定。Now, you can use the new msg parameter to write to the output binding from your function code. 将以下代码行添加到成功响应之前,以便将 name 的值添加到 msg 输出绑定。Add the following line of code before the success response to add the value of name to the msg output binding.

msg.setValue(name);

使用输出绑定时,无需使用 Azure 存储 SDK 代码进行身份验证、获取队列引用或写入数据。When you use an output binding, you don't have to use the Azure Storage SDK code for authentication, getting a queue reference, or writing data. Functions 运行时和队列输出绑定将为你执行这些任务。The Functions runtime and queue output binding do those tasks for you.

run 方法现在应如以下示例所示:Your run method should now look like the following example:

public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    String name = request.getBody().orElse(query);

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
        .body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

更新测试Update the tests

由于原型还创建一组测试,因此需更新这些测试,以便处理 run 方法签名中的新 msg 参数。Because the archetype also creates a set of tests, you need to update these tests to handle the new msg parameter in the run method signature.

浏览到测试代码在 src/test/java 下的位置,打开 Function.java 项目文件,将 //Invoke 下的代码行替换为以下代码。Browse to the location of your test code under src/test/java, open the Function.java project file, and replace the line of code under //Invoke with the following code.

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

请注意,不需要编写任何用于身份验证、获取队列引用或写入数据的代码。 Observe that you don't need to write any code for authentication, getting a queue reference, or writing data. 在 Azure Functions 运行时和队列输出绑定中可以方便地处理所有这些集成任务。All these integration tasks are conveniently handled in the Azure Functions runtime and queue output binding.

在本地运行函数Run the function locally

  1. 通过从 LocalFunctionProj 文件夹启动本地 Azure Functions 运行时主机来运行函数:Run your function by starting the local Azure Functions runtime host from the LocalFunctionProj folder:

    func start
    

    在输出的末尾,应显示以下行:Toward the end of the output, the following lines should appear:

     ...
    
     Now listening on: http://0.0.0.0:7071
     Application started. Press Ctrl+C to shut down.
    
     Http Functions:
    
             HttpExample: [GET,POST] http://localhost:7071/api/HttpExample
     ...
    
     

    备注

    如果 HttpExample 未按如上所示出现,则可能是在项目的根文件夹外启动了主机。If HttpExample doesn't appear as shown above, you likely started the host from outside the root folder of the project. 在这种情况下,请按 Ctrl+C 停止主机,导航到项目的根文件夹,然后重新运行上一命令。In that case, use Ctrl+C to stop the host, navigate to the project's root folder, and run the previous command again.

  2. 将此输出中 HttpExample 函数的 URL 复制到浏览器,并追加查询字符串 ?name=<YOUR_NAME>,使完整 URL 类似于 http://localhost:7071/api/HttpExample?name=FunctionsCopy the URL of your HttpExample function from this output to a browser and append the query string ?name=<YOUR_NAME>, making the full URL like http://localhost:7071/api/HttpExample?name=Functions. 浏览器应会显示类似于 Hello Functions 的消息:The browser should display a message like Hello Functions:

    在浏览器中本地运行函数后的结果

  3. 当你发出请求时,启动项目时所在的终端还会显示日志输出。The terminal in which you started your project also shows log output as you make requests.

  4. 完成后,请按 Ctrl+C 并选择 y 以停止函数主机 。When you're done, use Ctrl+C and choose y to stop the functions host.

提示

在启动过程中,主机会下载并安装存储绑定扩展和其他 Microsoft 绑定扩展。During startup, the host downloads and installs the Storage binding extension and other Microsoft binding extensions. 之所以安装这些扩展,是因为默认情况下,已在 host.json 文件中使用以下属性启用了绑定扩展:This installation happens because binding extensions are enabled by default in the host.json file with the following properties:

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 2.0.0)"
    }
}

如果遇到任何与绑定扩展相关的错误,请检查上述属性是否在 host.json 中存在。If you encounter any errors related to binding extensions, check that the above properties are present in host.json.

查看 Azure 存储队列中的消息View the message in the Azure Storage queue

可以在 Azure 门户Azure 存储资源管理器中查看队列。You can view the queue in the Azure portal or in the Azure Storage Explorer. 也可以按以下步骤中所述,在 Azure CLI 中查看队列:You can also view the queue in the Azure CLI, as described in the following steps:

  1. 打开函数项目的 local.setting.json 文件,并复制连接字符串值。Open the function project's local.setting.json file and copy the connection string value. 在终端或命令窗口中运行以下命令,以创建名为 AZURE_STORAGE_CONNECTION_STRING 的环境变量(请在 <MY_CONNECTION_STRING> 位置粘贴特定的连接字符串)。In a terminal or command window, run the following command to create an environment variable named AZURE_STORAGE_CONNECTION_STRING, pasting your specific connection string in place of <MY_CONNECTION_STRING>. (创建此环境变量后,无需在使用 --connection-string 参数的每个后续命令中提供连接字符串。)(This environment variable means you don't need to supply the connection string to each subsequent command using the --connection-string argument.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (可选)使用 az storage queue list 命令查看帐户中的存储队列。(Optional) Use the az storage queue list command to view the Storage queues in your account. 此命令的输出应包含名为 outqueue 的队列,该队列是函数将其第一条消息写入该队列时创建的。The output from this command should include a queue named outqueue, which was created when the function wrote its first message to that queue.

    az storage queue list --output tsv
    
  3. 使用 az storage message get 命令读取此队列中的消息,队列名称应是前面在测试函数时使用的名称。Use the az storage message get command to read the message from this queue, which should be the first name you used when testing the function earlier. 该命令读取再删除该队列中的第一条消息。The command reads and removes the first message from the queue.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    由于消息正文是以 base64 编码格式存储的,因此,必须解码消息才能显示消息。Because the message body is stored base64 encoded, the message must be decoded before it's displayed. 执行 az storage message get 后,该消息将从队列中删除。After you execute az storage message get, the message is removed from the queue. 如果 outqueue 中只有一条消息,则再次运行此命令时不会检索到消息,而是收到错误。If there was only one message in outqueue, you won't retrieve a message when you run this command a second time and instead get an error.

将项目重新部署到 AzureRedeploy the project to Azure

在本地验证函数已将消息写入 Azure 存储队列后,接下来可以重新部署项目以更新 Azure 上运行的终结点。Now that you've verified locally that the function wrote a message to the Azure Storage queue, you can redeploy your project to update the endpoint running on Azure.

LocalFunctionsProj 文件夹中,使用 func azure functionapp publish 命令重新部署项目(请将 <APP_NAME> 替换为你的应用的名称)。In the LocalFunctionsProj folder, use the func azure functionapp publish command to redeploy the project, replacing<APP_NAME> with the name of your app.

func azure functionapp publish <APP_NAME>

在本地项目文件夹中,使用以下 Maven 命令重新发布项目:In the local project folder, use the following Maven command to republish your project:

mvn azure-functions:deploy

在 Azure 中验证Verify in Azure

  1. 像在上一篇快速入门中一样,使用浏览器或 CURL 来测试重新部署的函数。As in the previous quickstart, use a browser or CURL to test the redeployed function.

    将 publish 命令的输出中显示的完整“调用 URL”复制到浏览器的地址栏,并追加查询参数 &name=FunctionsCopy the complete Invoke URL shown in the output of the publish command into a browser address bar, appending the query parameter &name=Functions. 浏览器显示的输出应与本地运行函数时显示的输出类似。The browser should display similar output as when you ran the function locally.

    在 Azure 上运行函数后浏览器中的输出

  2. 按上一部分所述再次检查存储队列,验证它是否包含已写入到其中的新消息。Examine the Storage queue again, as described in the previous section, to verify that it contains the new message written to the queue.

清理资源Clean up resources

完成后,请使用以下命令删除资源组及其包含的所有资源,以免产生额外的费用。After you've finished, use the following command to delete the resource group and all its contained resources to avoid incurring further costs.

az group delete --name AzureFunctionsQuickstart-rg

后续步骤Next steps

现已更新 HTTP 触发的函数,使其将数据写入存储队列。You've updated your HTTP triggered function to write data to a Storage queue. 现在,可以详细了解如何使用 Core Tools 和 Azure CLI 通过命令行进行 Functions 开发:Now you can learn more about developing Functions from the command line using Core Tools and Azure CLI: