包含: 托管集成 —&—
Client 集成
Azure Service Bus 是一个完全托管的企业消息中转站,其中包含消息队列和发布-订阅主题。 通过 AspireAzure Service Bus 集成,可以从 Azure Service Bus 应用程序连接到 .NET 实例。
托管集成
托管 AspireAzure Service Bus 集成将各种服务总线资源建模为以下类型:
- AzureServiceBusResource:表示 Azure Service Bus 资源。
- AzureServiceBusQueueResource:表示 Azure Service Bus 队列资源。
- AzureServiceBusSubscriptionResource:表示 Azure Service Bus 订阅资源。
- AzureServiceBusTopicResource:表示 Azure Service Bus 主题资源。
- AzureServiceBusEmulatorResource:表示 Azure Service Bus 模拟器资源。
若要访问这些类型和 API 来表达它们,请添加 .📦AspireHosting.Azure.AppHost 项目中的 ServiceBus NuGet 包。
dotnet add package Aspire.Hosting.Azure.ServiceBus
有关详细信息,请参阅 dotnet add package 或 在.NET应用程序中管理包依赖项。
添加 Azure Service Bus 资源
在 AppHost 项目中,调用 AddAzureServiceBus 添加并返回 Azure Service Bus 资源生成器。
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging");
// After adding all resources, run the app...
将 a AzureServiceBusResource 添加到 AppHost 时,它会公开其他有用的 API 来添加队列和主题。 换句话说,在添加任何其他服务总线资源之前,必须先添加AzureServiceBusResource。
重要
调用 AddAzureServiceBus时,它会隐式调用 AddAzureProvisioning,这增加了在应用启动期间动态生成 Azure 资源的支持。 应用必须配置相应的订阅和位置。 有关详细信息,请参阅 “配置”。
连接到现有 Azure Service Bus 命名空间
你可能希望连接到一个现有的 Azure Service Bus 命名空间。 链接调用以标注你的 AzureServiceBusResource 是现有资源:
var builder = DistributedApplication.CreateBuilder(args);
var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");
var serviceBus = builder.AddAzureServiceBus("messaging")
.AsExisting(existingServiceBusName, existingServiceBusResourceGroup);
builder.AddProject<Projects.WebApplication>("web")
.WithReference(serviceBus);
// After adding all resources, run the app...
重要
调用RunAsExisting或PublishAsExistingAsExisting处理订阅中Azure已存在的资源的方法时,必须将某些配置值添加到 AppHost,以确保Aspire找到它们。 必要的配置值包括 SubscriptionId、 AllowResourceGroupCreation、 ResourceGroup 和 Location。 如果您不设置它们,仪表板中就会出现“缺少配置”错误 Aspire。 有关如何设置它们的详细信息,请参阅 “配置”。
有关将 Azure Service Bus 资源视为现有资源的详细信息,请参阅 “使用现有 Azure 资源”。
注
或者,可以向 AppHost 添加连接字符串,而不是表示 Azure Service Bus 资源。 此方法属于弱类型,不适用于角色分配或基础结构自定义。 有关详细信息,请参阅 添加包含连接字符串的现有 Azure 资源。
添加 Azure Service Bus 队列
若要添加 Azure Service Bus 队列,请在 AddServiceBusQueue上调用 IResourceBuilder<AzureServiceBusResource> 方法:
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging");
var queue = serviceBus.AddServiceBusQueue("queue");
// After adding all resources, run the app...
调用 AddServiceBusQueue(IResourceBuilder<AzureServiceBusResource>, String, String)时,它将服务总线资源配置为具有名为 queue的队列。 表达了 messaging 服务总线资源与其子 queue 之间的明确父子关系。 队列是在服务总线命名空间中创建的,该命名空间由前面添加的 AzureServiceBusResource 表示。 有关详细信息,请参阅队列、主题和订阅。Azure Service Bus
添加 Azure Service Bus 主题和订阅
若要添加 Azure Service Bus 主题,请在 AddServiceBusTopic上调用 IResourceBuilder<AzureServiceBusResource> 方法:
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging");
var topic = serviceBus.AddServiceBusTopic("topic");
// After adding all resources, run the app...
调用 AddServiceBusTopic(IResourceBuilder<AzureServiceBusResource>, String, String)时,它将服务总线资源配置为具有名为 topic的主题。 主题是在你之前添加的 AzureServiceBusResource 所表示的服务总线命名空间中创建的。
若要添加主题的订阅,请在 AddServiceBusSubscription 上调用 IResourceBuilder<AzureServiceBusTopicResource> 方法,并使用 WithProperties 方法对其进行配置:
using Aspire.Hosting.Azure;
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging");
var topic = serviceBus.AddServiceBusTopic("topic");
topic.AddServiceBusSubscription("sub1")
.WithProperties(subscription =>
{
subscription.MaxDeliveryCount = 10;
subscription.Rules.Add(
new AzureServiceBusRule("app-prop-filter-1")
{
CorrelationFilter = new()
{
ContentType = "application/text",
CorrelationId = "id1",
Subject = "subject1",
MessageId = "msgid1",
ReplyTo = "someQueue",
ReplyToSessionId = "sessionId",
SessionId = "session1",
SendTo = "xyz"
}
});
});
// After adding all resources, run the app...
上述代码不仅添加了一个主题,还为该主题创建并配置了一个名为 sub1 的订阅。 订阅的最大传递计数是 10,还有一个名为 app-prop-filter-1的规则。 规则是一个关联筛选器,它基于 ContentType、CorrelationId、Subject、MessageId、ReplyTo、ReplyToSessionId、SessionId和 SendTo 属性筛选消息。
有关详细信息,请参阅队列、主题和订阅。Azure Service Bus
添加 Azure Service Bus 模拟器资源
若要添加 Azure Service Bus 模拟器资源,请将对 <IResourceBuilder<AzureServiceBusResource>> 的调用链接到 RunAsEmulator API:
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging")
.RunAsEmulator();
// After adding all resources, run the app...
调用 RunAsEmulator时,它会将服务总线资源配置为使用模拟器在本地运行。 在本例中,Azure Service Bus模拟器是一个仿真器。
Azure Service Bus 模拟器提供了一个免费的本地环境来测试 Azure Service Bus 应用,它是 AspireAzure 托管集成的完美伴侣。 模拟器并未安装,而是以容器的形式通过 Aspire 访问。 将容器添加到 AppHost 时,如前面的示例 mcr.microsoft.com/azure-messaging/servicebus-emulator 所示,其中包含映像(以及配套 mcr.microsoft.com/azure-sql-edge 映像),它会在 AppHost 启动时创建并启动容器。 有关详细信息,请参阅 容器资源生命周期。
配置服务总线模拟器容器
有各种配置可用于容器资源,例如,可以配置容器的端口,或者提供一个整体性配置 JSON,覆盖所有内容。
配置服务总线模拟器容器主机端口
默认情况下,服务总线模拟器容器在配置 Aspire时公开以下终结点:
| 端点 | 图像 | 集装箱码头 | 主机端口 |
|---|---|---|---|
emulator |
mcr.microsoft.com/azure-messaging/servicebus-emulator |
5672 | 动态的 |
tcp |
mcr.microsoft.com/mssql/server |
1433 | 动态的 |
默认情况下,侦听的端口是动态的。 容器启动时,端口将映射到主机上的随机端口。 若要配置终结点端口,请对 RunAsEmulator 方法提供的容器资源生成器进行链式调用,然后对 WithHostPort(IResourceBuilder<AzureServiceBusEmulatorResource>, Nullable<Int32>) 进行链式调用,如以下示例所示:
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging").RunAsEmulator(
emulator =>
{
emulator.WithHostPort(7777);
});
// After adding all resources, run the app...
前面的代码将服务总线模拟器容器的现有 emulator 终结点配置为侦听端口 7777。 服务总线模拟器容器的端口映射到主机端口,如下表所示:
| 终结点名称 | 端口映射 (container:host) |
|---|---|
emulator |
5672:7777 |
配置服务总线模拟器容器 JSON 配置
服务总线模拟器自动生成与配置资源中的此 config.json 文件类似的配置。 你可以完全替代此生成的文件,也可以使用配置的 JSON 表示形式更新 JsonNode 配置。
若要提供自定义 JSON 配置文件,请调用 WithConfigurationFile(IResourceBuilder<AzureServiceBusEmulatorResource>, String) 方法:
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging").RunAsEmulator(
emulator =>
{
emulator.WithConfigurationFile(
path: "./messaging/custom-config.json");
});
前面的代码将服务总线模拟器容器配置为使用位于 JSON的自定义 ./messaging/custom-config.json 配置文件。 若要替代默认配置中的特定属性,请调用 WithConfiguration(IResourceBuilder<AzureServiceBusEmulatorResource>, Action<JsonNode>) 方法:
var builder = DistributedApplication.CreateBuilder(args);
var serviceBus = builder.AddAzureServiceBus("messaging").RunAsEmulator(
emulator =>
{
emulator.WithConfiguration(
(JsonNode configuration) =>
{
var userConfig = configuration["UserConfig"];
var ns = userConfig["Namespaces"][0];
var firstQueue = ns["Queues"][0];
var properties = firstQueue["Properties"];
properties["MaxDeliveryCount"] = 5;
properties["RequiresDuplicateDetection"] = true;
properties["DefaultMessageTimeToLive"] = "PT2H";
});
});
// After adding all resources, run the app...
前面的代码从默认配置中检索 UserConfig 节点。 然后,它会更新第一个队列的属性,将 MaxDeliveryCount 设置为 5,将 RequiresDuplicateDetection 设置为 true,并将 DefaultMessageTimeToLive 设置为 2 hours。
预配生成的 Bicep
如果你是 Bicep 的新手,Bicep 是一种特定于域的语言,用于定义 Azure 资源。 使用 Aspire时,无需手动编写 Bicep,而是预配 API 会为你生成 Bicep。 发布应用时,生成的 Bicep 文件将与清单文件一同输出。 添加 Azure Service Bus 资源时,会生成以下 Bicep:
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param sku string = 'Standard'
resource service_bus 'Microsoft.ServiceBus/namespaces@2024-01-01' = {
name: take('servicebus-${uniqueString(resourceGroup().id)}', 50)
location: location
properties: {
disableLocalAuth: true
}
sku: {
name: sku
}
tags: {
'aspire-resource-name': 'service-bus'
}
}
output serviceBusEndpoint string = service_bus.properties.serviceBusEndpoint
output name string = service_bus.name
前面的 Bicep 是预配 Azure Service Bus 命名空间资源的模块。 此外,在单独的模块中为 Azure 资源创建角色分配:
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param service_bus_outputs_name string
param principalType string
param principalId string
resource service_bus 'Microsoft.ServiceBus/namespaces@2024-01-01' existing = {
name: service_bus_outputs_name
}
resource service_bus_AzureServiceBusDataOwner 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(service_bus.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')
principalType: principalType
}
scope: service_bus
}
除了服务总线命名空间外,它还预配 Azure 数据所有者的 Azure 基于角色的访问控制 (Azure Service Bus RBAC) 内置角色。 该角色被分配给服务总线命名空间所属的资源组。 有关详细信息,请参阅 Azure Service Bus 数据所有者。
自定义预配基础结构
所有 AspireAzure 资源都是 AzureProvisioningResource 类型的子类。 这类型通过提供用于配置 Azure 资源的流畅 API 来允许自定义生成的 Bicep - ConfigureInfrastructure<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure>) API。 例如,你可以配置 SKU、位置等。 以下示例演示如何自定义 Azure Service Bus 资源:
builder.AddAzureServiceBus("service-bus")
.ConfigureInfrastructure(infra =>
{
var serviceBusNamespace = infra.GetProvisionableResources()
.OfType<ServiceBusNamespace>()
.Single();
serviceBusNamespace.Sku = new ServiceBusSku
{
Name = ServiceBusSkuName.Premium
};
serviceBusNamespace.Tags.Add("ExampleKey", "Example value");
});
前面的代码:
- 链接对 ConfigureInfrastructure API 的调用:
- 基础设施参数是 AzureResourceInfrastructure 类型的实例。
- 通过调用 GetProvisionableResources() 方法检索可预配资源。
- 系统会检索单个 ServiceBusNamespace。
- 系统使用 ServiceBusNamespace.Sku 创建 ServiceBusSkuTier.Premium
- 标记将添加到服务总线命名空间,其键为
ExampleKey,值为Example value。
还有更多配置选项可用于自定义 Azure Service Bus 资源。 有关详细信息,请参阅 Azure.Provisioning.ServiceBus。 有关详细信息,请参阅Azure.Provisioning 自定义。
托管集成运行状况检查
托管集成 Azure Service Bus 会自动为服务总线资源添加运行状况检查。 运行状况检查会验证服务总线是否正在运行,以及是否可以与其建立连接。
托管集成依赖于 📦 AspNetCore.HealthChecks.AzureServiceBus NuGet 包。
Client 集成
若要开始进行 AspireAzure Service Bus 客户端集成,请在使用客户端的项目(即,使用服务总线客户端的应用程序的项目)中安装 📦Aspire.Azure.Messaging.ServiceBus NuGet 包。 服务总线客户端集成会注册一个 ServiceBusClient 实例,该实例可用于与服务总线交互。
dotnet add package Aspire.Azure.Messaging.ServiceBus
添加 Service Bus 客户端
在您的客户端消费项目中的 Program.cs 文件中,对任何 AddAzureServiceBusClient 调用 IHostApplicationBuilder 扩展方法,以注册 ServiceBusClient,以便通过依赖注入容器进行使用。 该方法采用连接名称参数。
builder.AddAzureServiceBusClient(connectionName: "messaging");
然后,可以使用依赖项注入检索 ServiceBusClient 实例。 例如,若要从示例服务检索连接,
public class ExampleService(ServiceBusClient client)
{
// Use client...
}
有关依赖项注入的详细信息,请参阅 .NET 依赖项注入。
选择正确的连接名称
调用 AddAzureServiceBusClient()时,正确的值取决于在 AppHost 中传递给客户端的对象。
例如,如果在 AppHost 中使用此代码:
var serviceBus = builder.AddAzureServiceBus("messaging");
var apiService = builder.AddProject<Projects.Example_ApiService>("apiservice")
.WithReference(serviceBus);
然后,在客户端使用程序中添加服务总线的正确代码为:
builder.AddAzureServiceBusClient(connectionName: "messaging");
但是,如果您在 AppHost 中创建并传递了 Service Bus 主题:
var serviceBus = builder.AddAzureServiceBus("messaging");
var topic = serviceBus.AddServiceBusTopic("myTopic");
var apiService = builder.AddProject<Projects.Example_ApiService>("apiservice")
.WithReference(topic);
然后,在客户端使用程序中添加服务总线主题的正确代码为:
builder.AddAzureServiceBusClient(connectionName: "myTopic");
有关详细信息,请参阅“添加资源”和“添加Azure Service BusAzure Service Bus主题”和“订阅”。
添加键控服务总线客户端
在某些情况下,可能需要使用不同的连接名称注册多个 ServiceBusClient 实例。 若要注册密钥服务总线客户端,请调用 AddKeyedAzureServiceBusClient 方法:
builder.AddKeyedAzureServiceBusClient(name: "mainBus");
builder.AddKeyedAzureServiceBusClient(name: "loggingBus");
重要
使用密钥服务时,预计您的服务总线资源需配置两个命名总线,一个用于mainBus,一个用于loggingBus。
然后,可以使用依赖项注入检索 ServiceBusClient 实例。 例如,若要从示例服务检索连接,
public class ExampleService(
[FromKeyedServices("mainBus")] ServiceBusClient mainBusClient,
[FromKeyedServices("loggingBus")] ServiceBusClient loggingBusClient)
{
// Use clients...
}
有关密钥服务的详细信息,请参阅 .NET 依赖关系注入:密钥服务。
配置
Aspire Azure Service Bus 集成提供了多个选项,用于根据项目的要求和约定配置连接。
使用连接字符串
使用 ConnectionStrings 配置部分中的连接字符串时,可以在调用 AddAzureServiceBusClient 方法时提供连接字符串的名称:
builder.AddAzureServiceBusClient("messaging");
然后,从 ConnectionStrings 配置部分检索连接字符串:
{
"ConnectionStrings": {
"messaging": "Endpoint=sb://{namespace}.servicebus.windows.net/;SharedAccessKeyName={keyName};SharedAccessKey={key};"
}
}
有关如何设置此连接字符串格式的详细信息,请参阅 ConnectionString 文档。
使用配置提供程序
Aspire
Azure Service Bus 集成支持 Microsoft.Extensions.Configuration。 它使用 AzureMessagingServiceBusSettings 键从配置中加载 Aspire:Azure:Messaging:ServiceBus。 以下代码片段是一个 appsettings.json 文件的示例,该文件配置了一些选项:
{
"Aspire": {
"Azure": {
"Messaging": {
"ServiceBus": {
"ConnectionString": "Endpoint=sb://{namespace}.servicebus.windows.net/;SharedAccessKeyName={keyName};SharedAccessKey={key};",
"DisableTracing": false
}
}
}
}
}
有关完整的服务总线客户端集成 JSON 架构,请参阅 Aspire.Azure.Messaging.ServiceBus/ConfigurationSchema.json.
使用命名配置
集成 AspireAzure Service Bus 支持命名配置,通过该配置,可以使用不同的设置来配置同一资源类型的多个实例。 命名配置使用连接名称作为主配置部分下的密钥。
{
"Aspire": {
"Azure": {
"Messaging": {
"ServiceBus": {
"bus1": {
"ConnectionString": "Endpoint=sb://namespace1.servicebus.windows.net/;SharedAccessKeyName=keyName;SharedAccessKey=key;",
"DisableTracing": false
},
"bus2": {
"ConnectionString": "Endpoint=sb://namespace2.servicebus.windows.net/;SharedAccessKeyName=keyName;SharedAccessKey=key;",
"DisableTracing": true
}
}
}
}
}
}
在此示例中,当调用bus1时,可以使用bus2和AddAzureServiceBusClient作为连接名称。
builder.AddAzureServiceBusClient("bus1");
builder.AddAzureServiceBusClient("bus2");
命名配置优先于顶级配置。 如果同时提供这两种设置,则命名配置中的设置将替代顶级设置。
使用内联委托
您还可以传递 Action<AzureMessagingServiceBusSettings> configureSettings 委托以在代码中直接设置某些或所有选项,例如禁用跟踪功能。
builder.AddAzureServiceBusClient(
"messaging",
static settings => settings.DisableTracing = true);
还可以使用 Azure.Messaging.ServiceBus.ServiceBusClientOptions 方法的可选 Action<ServiceBusClientOptions> configureClientOptions 参数来设置 AddAzureServiceBusClient。 例如,为此客户端发出的所有请求设置 ServiceBusClientOptions.Identifier 用户代理标头后缀:
builder.AddAzureServiceBusClient(
"messaging",
configureClientOptions:
clientOptions => clientOptions.Identifier = "myapp");
Client 集成运行状况检查
默认情况下,Aspire 集成会为所有服务启用健康检查。 有关详细信息,请参阅 Aspire 集成概述。
Aspire Azure Service Bus 集成:
- 当 AzureMessagingServiceBusSettings.DisableTracing 为
false时添加运行状况检查,该检查会尝试连接到服务总线。 - 与
/healthHTTP 端点集成,该端点规定所有注册的健康检查必须通过,应用才能被视为已准备好接收流量。
可观测性和遥测
Aspire 集成会自动设置日志记录、跟踪和指标配置,这些配置有时称为 可观测性支柱。 有关集成可观测性和遥测的详细信息,请参阅 Aspire 集成概述。 根据支持服务,某些集成可能仅支持其中一些功能。 例如,某些集成支持日志记录和跟踪,但不支持指标。 还可以使用 “配置” 部分中介绍的技术禁用遥测功能。
日志记录
Aspire Azure Service Bus 集成使用以下日志类别:
Azure.CoreAzure.IdentityAzure-Messaging-ServiceBus
除了为失败的请求获取 Azure Service Bus 请求诊断之外,还可以配置延迟阈值来确定将记录哪些成功的 Azure Service Bus 请求诊断。 对于点操作,默认值为 100 毫秒,非点操作的默认值为 500 毫秒。
builder.AddAzureServiceBusClient(
"messaging",
configureClientOptions:
clientOptions => {
clientOptions.ServiceBusClientTelemetryOptions = new()
{
ServiceBusThresholdOptions = new()
{
PointOperationLatencyThreshold = TimeSpan.FromMilliseconds(50),
NonPointOperationLatencyThreshold = TimeSpan.FromMilliseconds(300)
}
};
});
跟踪
Aspire Azure Service Bus 集成将通过 OpenTelemetry 生成以下跟踪活动:
MessageServiceBusSender.SendServiceBusSender.ScheduleServiceBusSender.CancelServiceBusReceiver.ReceiveServiceBusReceiver.ReceiveDeferredServiceBusReceiver.PeekServiceBusReceiver.AbandonServiceBusReceiver.CompleteServiceBusReceiver.DeadLetterServiceBusReceiver.DeferServiceBusReceiver.RenewMessageLockServiceBusSessionReceiver.RenewSessionLockServiceBusSessionReceiver.GetSessionStateServiceBusSessionReceiver.SetSessionStateServiceBusProcessor.ProcessMessageServiceBusSessionProcessor.ProcessSessionMessageServiceBusRuleManager.CreateRuleServiceBusRuleManager.DeleteRuleServiceBusRuleManager.GetRules
Azure Service Bus 跟踪目前处于预览版阶段,因此,你必须设置试验开关以确保发出跟踪。
AppContext.SetSwitch("Azure.Experimental.EnableActivitySource", true);
有关详细信息,请参阅 Azure Service Bus:通过服务总线消息传送进行分布式跟踪和关联。
指标
由于 Aspire SDK 的限制,Azure Service BusAzure 集成目前默认不支持度量指标。