消息路由能够将遥测数据从 IoT 设备发送到内置的与事件中心兼容的终结点或自定义终结点,例如,Blob 存储、服务总线队列、服务总线主题和事件中心。 若要配置自定义消息路由,请创建路由查询来自定义与特定条件匹配的路由。 设置完成后,引入的数据将通过 IoT 中心自动路由到终结点。 如果某条消息与任何定义的路由查询不匹配,它会被路由到默认终结点。
本教程包括 2 个部分,介绍如何通过 IoT 中心设置和使用这些自定义路由查询。 将消息从 IoT 设备路由到多个终结点中的一个,包括 Blob 存储和服务总线队列。 路由到服务总线队列的消息将由逻辑应用拾取,并通过电子邮件发送。 未定义自定义消息路由的消息将发送到默认终结点,然后由 Azure 流分析拾取,可在 Power BI 中直观查看。
若要完成本教程的第 1 和第 2 部分,请执行以下任务:
第 I 部分:创建资源并设置消息路由
- 创建资源 - IoT 中心、存储帐户、服务总线队列和模拟设备。 使用 Azure 门户、Azure 资源管理器模板、Azure CLI 或 Azure PowerShell 即可完成此操作。
- 在 IoT 中心为存储帐户和服务总线队列配置终结点和消息路由。
第 II 部分:将消息发送到中心并查看路由的结果
- 创建一个逻辑应用,该应用将在消息添加到服务总线队列时触发,并发送电子邮件。
- 下载并运行应用,该应用模拟 IoT 设备将消息发送到中心,以获得不同的路由选择。
- 为发送至默认终结点的数据创建 Power BI 可视化。
- 查看结果...
- ...在服务总线队列和电子邮件中。
- ...在存储帐户中。
- ...在 Power BI 可视化中。
先决条件
对于本教程的第 1 部分:
- 必须拥有 Azure 订阅。 如果没有 Azure 订阅,请在开始前创建一个试用版订阅。
对于本教程的第 2 部分:
必须事先完成本教程的第 1 部分,并保留一些可用的资源。
安装 Visual Studio。
有权访问用于分析默认终结点的流分析的 Power BI 帐户。 (免费试用 Power BI。)
提供一个用于发送通知电子邮件的工作或学校帐户。
确保已在防火墙中打开端口 8883。 本教程中的示例使用 MQTT 协议,该协议通过端口 8883 进行通信。 在某些公司和教育网络环境中,此端口可能被阻止。 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)。
创建基础资源
在配置消息路由之前,需创建 IoT 中心、存储帐户和服务总线队列。 可以参阅适用于本教程第 1 部分的四篇文章中的一篇来创建这些资源:Azure门户、Azure 资源管理器模板、Azure CLI 或 Azure PowerShell。
为所有资源使用相同的资源组和位置。 在本教程结束后,可以通过删除资源组一次性删除所有资源。
下面是将在以下部分中执行的步骤摘要:
创建资源组。
在 S1 层级中创建 IoT 中心。 将使用者组添加到 IoT 中心。 检索数据时,Azure 流分析使用使用者组。
注意
必须使用付费层中的 IoT 中心来完成本教程。 免费层只允许设置一个终结点,但本教程需要多个终结点。
使用 Standard_LRS 副本创建标准 V1 存储帐户。
创建服务总线命名空间和队列。
为发送消息到中心的模拟设备创建设备标识。 保存测试阶段的密钥。 (如果创建资源管理器模板,则会在部署模板后执行此操作。)
下载脚本(可选)
在本教程的第二部分,我们将下载并运行一个 Visual Studio 应用程序,以将消息发送到 IoT 中心。 下载内容的某个文件夹中包含 Azure 资源管理器模板和参数文件,以及 Azure CLI 和 PowerShell 脚本。
若要查看已完成的脚本,请下载 Azure IoT C# 示例。 解压 main.zip 文件。 Azure CLI 脚本位于 /iot-hub/Tutorials/Routing/SimulatedDevice/resources/ 中,其文件名为 iothub_routing_psh.ps1。
创建资源
首先使用 PowerShell 创建资源。
使用 PowerShell 创建基本资源
将以下脚本复制粘贴到本地 Shell 中,然后按 Enter。 系统每次运行脚本中的一行。 该脚本的第一节将创建本教程所需的基本资源,包括存储帐户、IoT 中心、服务总线命名空间和服务总线队列。 在学习本教程的过程中,请将每个脚本块复制粘贴到本地 Shell,以运行。
有几个资源名称必须全局唯一,例如 IoT 中心名称和存储帐户名称。 为方便进行标识,这些资源名称的后面追加了名为 randomValue 的随机字母数字值。 randomValue 在脚本的顶部生成一次,并根据需要追加到整个脚本中的资源名称。 如果不想要使用随机后缀,可将其设置为空字符串或特定值。
重要
路由脚本也会使用初始脚本中设置的变量,因此,请在同一本地 Shell 会话中运行所有脚本。 如果打开新的会话来运行用于设置路由的脚本,则多个变量将会缺少值。
# This command retrieves the subscription id of the current Azure account.
# This field is used when setting up the routing queries.
$subscriptionID = (Get-AzContext).Subscription.Id
# Concatenate this number onto the resources that have to be globally unique.
# You can set this to "" or to a specific value if you don't want it to be random.
# This retrieves the first 6 digits of a random value.
$randomValue = "$(Get-Random)".Substring(0,6)
# Set the values for the resource names that don't have to be globally unique.
$location = "China North"
$resourceGroup = "ContosoResources"
$iotHubConsumerGroup = "ContosoConsumers"
$containerName = "contosoresults"
# Create the resource group to be used
# for all resources for this tutorial.
New-AzResourceGroup -Name $resourceGroup -Location $location
# The IoT hub name must be globally unique,
# so add a random value to the end.
$iotHubName = "ContosoTestHub" + $randomValue
Write-Host "IoT hub name is " $iotHubName
# Create the IoT hub.
New-AzIotHub -ResourceGroupName $resourceGroup `
-Name $iotHubName `
-SkuName "S1" `
-Location $location `
-Units 1
# Add a consumer group to the IoT hub.
Add-AzIotHubEventHubConsumerGroup -ResourceGroupName $resourceGroup `
-Name $iotHubName `
-EventHubConsumerGroupName $iotHubConsumerGroup
# The storage account name must be globally unique, so add a random value to the end.
$storageAccountName = "contosostorage" + $randomValue
Write-Host "storage account name is " $storageAccountName
# Create the storage account to be used as a routing destination.
# Save the context for the storage account
# to be used when creating a container.
$storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroup `
-Name $storageAccountName `
-Location $location `
-SkuName Standard_LRS `
-Kind Storage
# Retrieve the connection string from the context.
$storageConnectionString = $storageAccount.Context.ConnectionString
Write-Host "storage connection string = " $storageConnectionString
# Create the container in the storage account.
New-AzStorageContainer -Name $containerName `
-Context $storageAccount.Context
# The Service Bus namespace must be globally unique,
# so add a random value to the end.
$serviceBusNamespace = "ContosoSBNamespace" + $randomValue
Write-Host "Service Bus namespace is " $serviceBusNamespace
# Create the Service Bus namespace.
New-AzServiceBusNamespace -ResourceGroupName $resourceGroup `
-Location $location `
-Name $serviceBusNamespace
# The Service Bus queue name must be globally unique,
# so add a random value to the end.
$serviceBusQueueName = "ContosoSBQueue" + $randomValue
Write-Host "Service Bus queue name is " $serviceBusQueueName
# Create the Service Bus queue to be used as a routing destination.
New-AzServiceBusQueue -ResourceGroupName $resourceGroup `
-Namespace $serviceBusNamespace `
-Name $serviceBusQueueName `
-EnablePartitioning $False
创建模拟设备
接下来,创建设备标识并保存其密钥供之后使用。 此设备标识由模拟应用程序用来发送消息到 IoT 中心。 此功能在 PowerShell 中不可用,在使用 Azure 资源管理器模板时也不可用。 以下步骤介绍如何使用 Azure 门户创建模拟设备。
打开 Azure 门户并登录到 Azure 帐户。
选择“资源组”,然后选择你的资源组。 本教程使用 ContosoResources 。
在资源列表中,选择 IoT 中心。 本教程使用 ContosoTestHub 。 从中心窗格选择“IoT 设备”。
在“IoT 设备”窗格中选择“+ 添加设备” 。 在添加设备窗格中,填写设备 ID。 本教程使用 Contoso-Test-Device。 将密钥留空,勾选“自动生成密钥”。 确保已启用“将设备连接到 IoT 中心”。 选择“保存” 。
创建设备后,即可选择它来查看生成的密钥。 选择主密钥上的“复制”图标,将其保存在某个位置(如记事本)供本教程的测试阶段使用。
设置基本资源后,可以配置消息路由。
设置消息路由
根据模拟设备附加到消息的属性将消息路由到不同资源。 未自定义路由的消息将发送到默认终结点(消息/事件)。 在下一教程中,我们会将消息发送到 IoT 中心,看其如何路由到不同的目标。
值 | 结果 |
---|---|
级别=“storage” | 写入到 Azure 存储。 |
级别=“critical” | 写入服务总线队列。 逻辑应用从队列检索消息并使用 Office 365 通过电子邮件发送该消息。 |
default | 使用 Power BI 显示此数据。 |
第一步是设置终结点,以便将数据路由到其中。 第二步是设置使用该终结点的消息路由。 设置路由后,即可在门户中查看终结点和消息路由。
若要创建路由终结点,请使用 Add-AzIotHubRoutingEndpoint。 若要创建终结点的消息路由,请使用 Add-AzIotHubRoute。
路由到存储帐户
首先设置存储帐户的终结点,然后创建消息路由。
注意
可将数据以 Apache Avro 格式(默认)或 JSON 格式写入 Blob 存储。
编码格式只能在配置 Blob 存储终结点时设置。 不能更改已设置的终结点的格式。 使用 JSON 编码时,必须在消息系统属性中将 contentType 设置为 JSON,将 contentEncoding 设置为 UTF-8。
若要更详细地了解如何使用 Blob 存储终结点,请参阅有关如何路由到存储的指南。
以下是脚本使用的必须在本地 Shell 会话中设置的变量:
resourceGroup:此字段会在两个位置出现 - 请将两者设置为你的资源组。
name:此字段是要应用路由的 IoT 中心的名称。
endpointName:此字段是用于标识终结点的名称。
endpointType:此字段是终结点的类型。 此值必须设置为 azurestoragecontainer
、eventhub
、servicebusqueue
或 servicebustopic
。 在本文中,请将其设置为 azurestoragecontainer
。
subscriptionID:此字段设置为你的 Azure 帐户的 subscriptionID。
storageConnectionString:此值是从前述脚本设置的存储帐户中检索的。 路由使用此值来访问存储帐户。
containerName:此字段是存储帐户中要将数据写入到的容器的名称。
Encoding:请将此字段设置为 AVRO
或 JSON
。 这会指定存储数据的格式。 默认值为 AVRO。
routeName:此字段是要设置的路由的名称。
condition:此字段是用于筛选发送到此终结点的消息的查询。 路由到存储的消息的查询条件是 level="storage"
。
enabled:此字段默认为 true
,指示消息路由应在创建后启用。
将此脚本复制粘贴到本地 Shell 窗口。
##### ROUTING FOR STORAGE #####
$endpointName = "ContosoStorageEndpoint"
$endpointType = "azurestoragecontainer"
$routeName = "ContosoStorageRoute"
$condition = 'level="storage"'
下一步是为存储帐户创建路由终结点。 还可以指定用于存储结果的容器。 创建存储帐户时已创建该容器。
# Create the routing endpoint for storage.
# Specify 'AVRO' or 'JSON' for the encoding of the data.
Add-AzIotHubRoutingEndpoint `
-ResourceGroupName $resourceGroup `
-Name $iotHubName `
-EndpointName $endpointName `
-EndpointType $endpointType `
-EndpointResourceGroup $resourceGroup `
-EndpointSubscriptionId $subscriptionId `
-ConnectionString $storageConnectionString `
-ContainerName $containerName `
-Encoding AVRO
接下来,为存储终结点创建消息路由。 消息路由根据查询规范指定要将消息发送到何处。
# Create the route for the storage endpoint.
Add-AzIotHubRoute `
-ResourceGroupName $resourceGroup `
-Name $iotHubName `
-RouteName $routeName `
-Source DeviceMessages `
-EndpointName $endpointName `
-Condition $condition `
-Enabled
路由到服务总线队列
现在为服务总线队列设置路由。 若要检索服务总线队列的连接字符串,必须创建一个定义了正确权限的授权规则。 以下脚本为服务总线队列创建名为 sbauthrule
的授权规则,并将权限设置为 Listen Manage Send
。 设置此授权规则后,可以使用它来检索队列的连接字符串。
##### ROUTING FOR SERVICE BUS QUEUE #####
# Create the authorization rule for the Service Bus queue.
New-AzServiceBusAuthorizationRule `
-ResourceGroupName $resourceGroup `
-NamespaceName $serviceBusNamespace `
-Queue $serviceBusQueueName `
-Name "sbauthrule" `
-Rights @("Manage","Listen","Send")
现在,使用该授权规则来检索服务总线队列密钥。 稍后将在脚本中使用此授权规则来检索连接字符串。
$sbqkey = Get-AzServiceBusKey `
-ResourceGroupName $resourceGroup `
-NamespaceName $serviceBusNamespace `
-Queue $servicebusQueueName `
-Name "sbauthrule"
现在,为服务总线队列设置路由终结点和消息路由。 以下是脚本使用的必须在本地 Shell 会话中设置的变量:
endpointName:此字段是用于标识终结点的名称。
endpointType:此字段是终结点的类型。 此值必须设置为 azurestoragecontainer
、eventhub
、servicebusqueue
或 servicebustopic
。 在本文中,请将其设置为 servicebusqueue
。
routeName:此字段是要设置的路由的名称。
condition:此字段是用于筛选发送到此终结点的消息的查询。 路由到服务总线队列的消息的查询条件是 level="critical"
。
下面是服务总线队列的消息路由的 Azure PowerShell。
$endpointName = "ContosoSBQueueEndpoint"
$endpointType = "servicebusqueue"
$routeName = "ContosoSBQueueRoute"
$condition = 'level="critical"'
# If this script fails on the next statement (Add-AzIotHubRoutingEndpoint),
# put the pause in and run it again. Note that if you're running it
# interactively, you can just stop it and then run the rest, because
# you have already set the variables before you get to this point.
#
# Pause for 90 seconds to allow previous steps to complete.
# Then report it to the IoT team here:
# https://github.com/Azure/azure-powershell/issues
# pause for 90 seconds and then start again.
# This way, it if didn't get to finish before it tried to move on,
# now it will have time to finish first.
Start-Sleep -Seconds 90
# This command is the one that sometimes doesn't work. It's as if it doesn't have time to
# finish before it moves to the next line.
# The error from Add-AzIotHubRoutingEndpoint is "Operation returned an invalid status code 'BadRequest'".
# This command adds the routing endpoint, using the connection string property from the key.
# This will definitely work if you execute the Sleep command first (it's in the line above).
Add-AzIotHubRoutingEndpoint `
-ResourceGroupName $resourceGroup `
-Name $iotHubName `
-EndpointName $endpointName `
-EndpointType $endpointType `
-EndpointResourceGroup $resourceGroup `
-EndpointSubscriptionId $subscriptionId `
-ConnectionString $sbqkey.PrimaryConnectionString
# Set up the message route for the Service Bus queue endpoint.
Add-AzIotHubRoute `
-ResourceGroupName $resourceGroup `
-Name $iotHubName `
-RouteName $routeName `
-Source DeviceMessages `
-EndpointName $endpointName `
-Condition $condition `
-Enabled
在门户中查看消息路由
设置终结点和消息路由以后,即可在门户中查看其配置。 登录 Azure 门户,转到“资源组”。 接下来选择你的资源组,然后选择中心(在本教程中,中心名称以 ContosoTestHub
开头)。 此时会看到“IoT 中心”窗格。
在适用于 IoT 中心的选项中,选择“消息路由”。 此时会显示已成功设置的路由。
在“消息路由”屏幕上选择“自定义终结点”,查看为路由定义的终结点。
后续步骤
设置资源并配置消息路由后,请继续学习下一篇教程,了解如何将消息发送到 IoT 中心,并查看其如何路由到不同的目标。