Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
使用 Azure 服务总线输出绑定发送队列或主题消息。
有关设置和配置详细信息,请参阅概述。
重要
本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型已正式发布,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 有关 v4 模型工作原理的更多详细信息,请参阅 Azure Functions Node.js 开发人员指南。 要详细了解 v3 和 v4 之间的差异,请参阅迁移指南。
Azure Functions 支持两种 Python 编程模型。 定义绑定的方式取决于选择的编程模型。
使用 Python v2 编程模型,可以直接在 Python 函数代码中使用修饰器定义绑定。 有关详细信息,请参阅 Python 开发人员指南。
本文同时支持两个编程模型。
示例
可使用以下 C# 模式之一来创建 C# 函数:
-
独立辅助角色模型:编译的 C# 函数,该函数在独立于运行时的工作进程中运行。 需要独立工作进程才能支持在 LTS 和非 LTS 版 .NET 和 .NET Framework 上运行的 C# 函数。 独立工作进程函数的扩展使用
Microsoft.Azure.Functions.Worker.Extensions.*命名空间。 -
进程内模型:编译的 C# 函数,该函数在与 Functions 运行时相同的进程中运行。 在此模型的变体中,可以使用 C# 脚本运行 Functions,该脚本主要用于 C# 门户编辑。 进程内函数的扩展使用
Microsoft.Azure.WebJobs.Extensions.*命名空间。
重要
对进程内模型的支持将于 2026 年 11 月 10 日结束。 为获得完全支持,强烈建议将应用迁移到独立工作模型。
此代码定义并初始化 ILogger:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace SampleApp
{
/// <summary>
/// Samples demonstrating binding to the <see cref="ServiceBusReceivedMessage"/> type.
/// </summary>
public class ServiceBusReceivedMessageFunctions
{
//<docsnippet_servicebusmessage_createlogger>
private readonly ILogger<ServiceBusReceivedMessageFunctions> _logger;
public ServiceBusReceivedMessageFunctions(ILogger<ServiceBusReceivedMessageFunctions> logger)
{
_logger = logger;
}
//</docsnippet_servicebusmessage_createlogger>
/// <summary>
/// This function demonstrates binding to a single <see cref="ServiceBusReceivedMessage"/>.
/// </summary>
//<docsnippet_servicebus_readmessage>
[Function(nameof(ServiceBusReceivedMessageFunction))]
[ServiceBusOutput("outputQueue", Connection = "ServiceBusConnection")]
public string ServiceBusReceivedMessageFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage message)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
var outputMessage = $"Output message created at {DateTime.Now}";
return outputMessage;
}
//</docsnippet_servicebus_readmessage>
/// <summary>
/// This function demonstrates binding to an array of <see cref="ServiceBusReceivedMessage"/>.
/// Note that when doing so, you must also set the <see cref="ServiceBusTriggerAttribute.IsBatched"/> property
/// to <value>true</value>.
/// </summary>
//<docsnippet_servicebus_readbatch>
[Function(nameof(ServiceBusReceivedMessageBatchFunction))]
public void ServiceBusReceivedMessageBatchFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", IsBatched = true)] ServiceBusReceivedMessage[] messages)
{
foreach (ServiceBusReceivedMessage message in messages)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
}
}
//</docsnippet_servicebus_readbatch>
/// <summary>
/// This functions demonstrates that it is possible to bind to both the ServiceBusReceivedMessage and any of the supported binding contract
/// properties at the same time. If attempting this, the ServiceBusReceivedMessage must be the first parameter. There is not
/// much benefit to doing this as all of the binding contract properties are available as properties on the ServiceBusReceivedMessage.
/// </summary>
[Function(nameof(ServiceBusReceivedMessageWithStringProperties))]
public void ServiceBusReceivedMessageWithStringProperties(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")]
ServiceBusReceivedMessage message, string messageId, int deliveryCount)
{
// The MessageId property and the messageId parameter are the same.
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message ID: {id}", messageId);
// Similarly the DeliveryCount property and the deliveryCount parameter are the same.
_logger.LogInformation("Delivery Count: {count}", message.DeliveryCount);
_logger.LogInformation("Delivery Count: {count}", deliveryCount);
}
//<docsnippet_servicebus_message_actions>
[Function(nameof(ServiceBusMessageActionsFunction))]
public async Task ServiceBusMessageActionsFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", AutoCompleteMessages = false)]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
//</docsnippet_servicebus_message_actions>
}
}
此示例演示一个 C# 函数,该函数接收消息并将其写入第二个队列:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace SampleApp
{
/// <summary>
/// Samples demonstrating binding to the <see cref="ServiceBusReceivedMessage"/> type.
/// </summary>
public class ServiceBusReceivedMessageFunctions
{
//<docsnippet_servicebusmessage_createlogger>
private readonly ILogger<ServiceBusReceivedMessageFunctions> _logger;
public ServiceBusReceivedMessageFunctions(ILogger<ServiceBusReceivedMessageFunctions> logger)
{
_logger = logger;
}
//</docsnippet_servicebusmessage_createlogger>
/// <summary>
/// This function demonstrates binding to a single <see cref="ServiceBusReceivedMessage"/>.
/// </summary>
//<docsnippet_servicebus_readmessage>
[Function(nameof(ServiceBusReceivedMessageFunction))]
[ServiceBusOutput("outputQueue", Connection = "ServiceBusConnection")]
public string ServiceBusReceivedMessageFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage message)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
var outputMessage = $"Output message created at {DateTime.Now}";
return outputMessage;
}
//</docsnippet_servicebus_readmessage>
/// <summary>
/// This function demonstrates binding to an array of <see cref="ServiceBusReceivedMessage"/>.
/// Note that when doing so, you must also set the <see cref="ServiceBusTriggerAttribute.IsBatched"/> property
/// to <value>true</value>.
/// </summary>
//<docsnippet_servicebus_readbatch>
[Function(nameof(ServiceBusReceivedMessageBatchFunction))]
public void ServiceBusReceivedMessageBatchFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", IsBatched = true)] ServiceBusReceivedMessage[] messages)
{
foreach (ServiceBusReceivedMessage message in messages)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
}
}
//</docsnippet_servicebus_readbatch>
/// <summary>
/// This functions demonstrates that it is possible to bind to both the ServiceBusReceivedMessage and any of the supported binding contract
/// properties at the same time. If attempting this, the ServiceBusReceivedMessage must be the first parameter. There is not
/// much benefit to doing this as all of the binding contract properties are available as properties on the ServiceBusReceivedMessage.
/// </summary>
[Function(nameof(ServiceBusReceivedMessageWithStringProperties))]
public void ServiceBusReceivedMessageWithStringProperties(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")]
ServiceBusReceivedMessage message, string messageId, int deliveryCount)
{
// The MessageId property and the messageId parameter are the same.
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message ID: {id}", messageId);
// Similarly the DeliveryCount property and the deliveryCount parameter are the same.
_logger.LogInformation("Delivery Count: {count}", message.DeliveryCount);
_logger.LogInformation("Delivery Count: {count}", deliveryCount);
}
//<docsnippet_servicebus_message_actions>
[Function(nameof(ServiceBusMessageActionsFunction))]
public async Task ServiceBusMessageActionsFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", AutoCompleteMessages = false)]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
//</docsnippet_servicebus_message_actions>
}
}
此示例使用带有 OutputType 对象的 HTTP 触发器来发送 HTTP 响应并写入输出消息。
[Function("HttpSendMsg")]
public async Task<OutputType> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext context)
{
_logger.LogInformation($"C# HTTP trigger function processed a request for {context.InvocationId}.");
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync("HTTP response: Message sent");
return new OutputType()
{
OutputEvent = "MyMessage",
HttpResponse = response
};
}
此代码定义了多输出类型 OutputType,其中包括 OutputEvent 上的服务总线输出绑定定义:
public class OutputType
{
[ServiceBusOutput("TopicOrQueueName", Connection = "ServiceBusConnection")]
public string OutputEvent { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
以下示例演示了一个 Java 函数,该函数在由 HTTP 请求触发时将消息发送到服务总线队列 myqueue。
@FunctionName("httpToServiceBusQueue")
@ServiceBusQueueOutput(name = "message", queueName = "myqueue", connection = "AzureServiceBusConnection")
public String pushToQueue(
@HttpTrigger(name = "request", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
final String message,
@HttpOutput(name = "response") final OutputBinding<T> result ) {
result.setValue(message + " has been sent.");
return message;
}
在 Java 函数运行时库中,对其值将写入服务总线队列的函数参数使用 @QueueOutput 注释。 参数类型应为 OutputBinding<T>,其中 T 是普通旧 Java 对象 (POJO) 的任何原生 Java 类型。
Java 函数也可将内容写入服务总线主题。 以下示例使用 @ServiceBusTopicOutput 注释来说明输出绑定的配置。
@FunctionName("sbtopicsend")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
@ServiceBusTopicOutput(name = "message", topicName = "mytopicname", subscriptionName = "mysubscription", connection = "ServiceBusConnection") OutputBinding<String> message,
final ExecutionContext context) {
String name = request.getBody().orElse("Azure Functions");
message.setValue(name);
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
以下示例显示计时器触发的 TypeScript 函数,该函数每 5 分钟发送一次队列消息。
import { app, InvocationContext, output, Timer } from '@azure/functions';
export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<string> {
const timeStamp = new Date().toISOString();
return `Message created at: ${timeStamp}`;
}
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
}),
handler: timerTrigger1,
});
若要输出多条消息,请返回一个数组而不是单个对象。 例如:
import { app, InvocationContext, output, Timer } from '@azure/functions';
export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<string[]> {
// <displayInDocs>
const timeStamp = new Date().toISOString();
const message = `Message created at: ${timeStamp}`;
return [`1: ${message}`, `2: ${message}`];
// </displayInDocs>
}
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
}),
handler: timerTrigger1,
});
以下示例显示计时器触发的 JavaScript 函数,该函数每 5 分钟发送一次队列消息。
const { app, output } = require('@azure/functions');
const serviceBusOutput = output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
});
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: serviceBusOutput,
handler: (myTimer, context) => {
const timeStamp = new Date().toISOString();
return `Message created at: ${timeStamp}`;
},
});
若要输出多条消息,请返回一个数组而不是单个对象。 例如:
const { app, output } = require('@azure/functions');
const serviceBusOutput = output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
});
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: serviceBusOutput,
handler: (myTimer, context) => {
// <displayInDocs>
const timeStamp = new Date().toISOString();
const message = `Message created at: ${timeStamp}`;
return [`1: ${message}`, `2: ${message}`];
// </displayInDocs>
},
});
以下示例演示了 function.json 文件中的服务总线输出绑定以及使用该绑定的 PowerShell 函数。
下面是 function.json 文件中的绑定数据:
{
"bindings": [
{
"type": "serviceBus",
"direction": "out",
"connection": "AzureServiceBusConnectionString",
"name": "outputSbMsg",
"queueName": "outqueue",
"topicName": "outtopic"
}
]
}
下面是创建消息作为函数输出的 PowerShell。
param($QueueItem, $TriggerMetadata)
Push-OutputBinding -Name outputSbMsg -Value @{
name = $QueueItem.name
employeeId = $QueueItem.employeeId
address = $QueueItem.address
}
以下示例演示如何在 Python 中写出到服务总线主题和服务总线队列。 该示例取决于是使用 v1 还是 v2 Python 编程模型。
此示例演示如何写出到服务总线主题。
import logging
import azure.functions as func
app = func.FunctionApp()
@app.route(route="put_message")
@app.service_bus_topic_output(arg_name="message",
connection="AzureServiceBusConnectionString",
topic_name="outTopic")
def main(req: func.HttpRequest, message: func.Out[str]) -> func.HttpResponse:
input_msg = req.params.get('message')
message.set(input_msg)
return 'OK'
此示例演示如何写出到服务总线队列。
import azure.functions as func
app = func.FunctionApp()
@app.route(route="put_message")
@app.service_bus_queue_output(
arg_name="msg",
connection="AzureServiceBusConnectionString",
queue_name="outqueue")
def put_message(req: func.HttpRequest, msg: func.Out[str]):
msg.set(req.get_body().decode('utf-8'))
return 'OK'
特性
进程内和独立工作进程 C# 库都使用属性来定义输出绑定。 C# 脚本改用 function.json 配置文件,如 C# 脚本指南中所述。
在 C# 类库中,使用 ServiceBusOutputAttribute 定义由输出写入的队列或主题。
下表说明了可使用特性设置的属性:
| 属性 | 说明 |
|---|---|
| EntityType | 将实体类型设置为 Queue(用于将消息发送到队列)或 Topic(将消息发送到主题)。 |
| QueueOrTopicName | 要向其发送消息的主题或队列的名称。 使用 EntityType 设置目标类型。 |
| 连接 | 指定如何连接到服务总线的应用设置或设置集合的名称。 请参阅连接。 |
修饰符
仅适用于 Python v2 编程模型。
对于使用修饰器定义的 Python v2 功能,支持 service_bus_topic_output 上的以下属性:
| 属性 | 说明 |
|---|---|
arg_name |
变量的名称,表示函数代码中的队列或主题消息。 |
queue_name |
队列名称。 仅在发送队列消息的情况下设置,不为主题设置。 |
topic_name |
主题名称。 仅在发送主题消息的情况下设置,不为队列设置。 |
connection |
指定如何连接到服务总线的应用设置或设置集合的名称。 请参阅连接。 |
对于使用 function.json 定义的 Python 函数,请参阅“配置”部分。
批注
使用 ServiceBusQueueOutput 和 ServiceBusTopicOutput 注释可以函数输出的形式写入消息。 使用这些注释修饰的参数必须声明为 OutputBinding<T>,其中 T 是与消息类型对应的类型。
配置
仅适用于 Python v1 编程模型。
下表解释了在 function.json 文件和 特性中设置的绑定配置属性。
| function.json 属性 | 说明 |
|---|---|
| type | 必须设置为 serviceBus。 在 Azure 门户中创建触发器时,会自动设置此属性。 |
| 方向 | 必须设置为 out。 在 Azure 门户中创建触发器时,会自动设置此属性。 |
| 名字 | 变量的名称,表示函数代码中的队列或主题消息。 设置为“$return”可引用函数返回值。 |
| 队列名称 | 队列名称。 仅在发送队列消息的情况下设置,不为主题设置。 |
| topicName | 主题名称。 仅在发送主题消息的情况下设置,不为队列设置。 |
| 连接 | 指定如何连接到服务总线的应用设置或设置集合的名称。 请参阅连接。 |
有关完整示例,请参阅示例部分。
使用情况
所有 C# 形式和扩展版本都支持以下输出参数类型:
| 类型 | 说明 |
|---|---|
| System.String | 如果要写入的消息是简单的文本,请使用此类型。 如果函数退出时参数值为 null,Functions 不创建消息。 |
| byte[] | 如果要写入二进制数据消息,请使用此类型。 如果函数退出时参数值为 null,Functions 不创建消息。 |
| 对象 | 如果消息包含 JSON,Functions 会将对象序列化为 JSON 消息负载。 如果函数退出时参数值为 null,Functions 将创建具有 null 对象的消息。 |
特定于消息的参数类型包含额外的消息元数据,并且不兼容 JSON 序列化。 因此,无法在隔离模型中将 ServiceBusMessage 与输出绑定一起使用。 输出绑定支持的具体类型取决于扩展包版本和所使用的 C# 模态。
如果希望函数写入单个消息,服务总线输出绑定可以绑定到以下类型:
| 类型 | 说明 |
|---|---|
string |
字符串格式的消息。 当消息为简单文本时使用。 |
byte[] |
消息的字节数。 |
| JSON 可序列化类型 | 表示消息的对象。 函数尝试将普通旧 CLR 对象 (POCO) 类型序列化为 JSON 数据。 |
如果希望函数写入多个消息,服务总线输出绑定可以绑定到以下类型:
| 类型 | 说明 |
|---|---|
T[],其中 T 是单消息类型之一 |
包含多个消息的数组。 每个条目表示一个消息。 |
对于其他输出方案,请直接在 Azure.Messaging.ServiceBus 中创建和使用 ServiceBusClient 和其他类型的服务总线。 有关使用依赖项注入从 Azure SDK 创建客户端类型的示例,请参阅 “注册 Azure 客户端 ”。
队列或主题必须已经存在;如果你指定了一个不存在的队列或主题,函数就会失败。
使用 Azure 服务总线 SDK 而不是内置的输出绑定。
通过 Push-OutputBinding cmdlet 可以输出到服务总线,你在其中传递的参数与 function.json 文件中绑定的名称参数指定的名称匹配。
输出函数参数必须定义为 func.Out[str] 或 func.Out[bytes]。 有关详细信息,请参阅输出示例。
或者,可以使用 Azure 服务总线 SDK ,而不是内置的输出绑定。
有关完整示例,请参阅示例部分。
连接
该connection属性是应用设置中一个键的引用,返回函数运行时用于连接扩展所用服务总线实例的值。 连接属性设置的值取决于连接类型:
-
管理身份连接:该
connection属性是由<CONNECTION_NAME_PREFIX>一组设置共享的,这些设置共同定义了基于身份的连接与服务总线的连接。 更多信息请参见 定义身份连接。 -
密钥保管库 引用:
connection属性设置返回一个 Azure 密钥保管库 引用,指向该 连接字符串 中心维护的位置。 更多信息请参见定义 密钥保管库 连接。 -
App Configuration 引用:
connection属性设置返回一个 Azure 应用程序配置 引用,返回一个 连接字符串 或 密钥保管库 引用。 更多信息请参见连接文章中的 Azure 应用程序配置。 -
Connection string:
connection属性设置返回 服务总线 实例的实际 连接字符串。 由于连接字符串包含共享的秘密密钥,你应尽量考虑使用管理身份连接。 更多信息请参见定义连接。
欲了解更多关于绑定连接的信息,请参见 Azure Functions 中的 Manage connection 。
若要获取连接字符串,请执行获取管理凭据中显示的步骤。 必须是服务总线命名空间的连接字符串,不限于特定的队列或主题。
如果应用设置名称以 AzureWebJobs开头,你可以只指定名称的其余部分。 例如,如果设置为connectionMyServiceBus,Functions 运行时将查找名为AzureWebJobsMyServiceBus“的应用”设置。 如果留connection空,函数运行时会使用应用设置中名为 AzureWebJobsServiceBus的默认服务总线 连接字符串。
权限缩放
服务总线扩展使用服务总线 Administration API(GetQueueRuntimePropertiesAsync / GetSubscriptionRuntimePropertiesAsync)来获取准确的消息计数,用于规模决策。 该 API 需要超出发送或接收消息所需的权限:
- SAS 连接字符串:SAS 策略必须包含 管理 访问权。
-
基于身份的连接:身份必须被分配为 Azure 服务总线 数据所有者角色,或包含 的自定义角色
Microsoft.ServiceBus/namespaces/*/read。
当连接缺少这些权限时,启动时不会看到错误。 相反,扩展默默地回归到基于窥视的消息估计,这种方法的准确性较低,可能导致延迟或错误的扩展决策。
Tip
对于依赖自动扩展的生产工作负载,可以包含管理访问权(SAS)或分配 Azure 服务总线 数据所有者角色(基于身份的连接),以确保规模行为的准确性。 应用程序设置中的连接字符串,名为 AzureWebJobsServiceBus。
异常和返回代码
| 绑定 | 参考 |
|---|---|
| 服务总线 | 服务总线错误代码 |
| 服务总线 | 服务总线限制 |