ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

IoT-For-Beginners 第 9 课:用 Azure Functions 无服务器架构将农田灌溉继电器控制逻辑迁移上云

IoT-For-Beginners 第 9 课:用 Azure Functions 无服务器架构将农田灌溉继电器控制逻辑迁移上云 IoT-For-Beginners 第 9 课用 Azure Functions 无服务器架构将农田灌溉继电器控制逻辑迁移上云【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇指南基于 IoT-For-Beginners 课程中“Migrate your application logic to the cloud”一课丹麦语版本位于 translations/da/2-farm/lessons/5-migrate-application-to-the-cloud/README.md英文原文位于 2-farm/lessons/5-migrate-application-to-the-cloud/README.md。在前一课中你已经把植物的土壤湿度监控与继电器水泵控制接入了云端的 Azure IoT Hub本课的核心任务是把“决定继电器何时开/关”的服务器端逻辑从自托管的 MQTT 监听程序迁移到云端的无服务器函数Serverless Functions中。读完后你将掌握Azure Functions 项目初始化、通过 Event Hub 兼容端点消费 IoT Hub 遥测消息、用 Registry Manager 向设备下发 Direct Method 指令以及把整套代码部署为云端 Function App 的完整操作流程。一、什么是无服务器计算无服务器Serverless计算的本质是编写小的代码块在云端响应各类事件而运行。事件发生时你的代码被加载并执行同时收到关于该事件的数据。事件可以来自多种来源Web 请求、队列中的消息、数据库变更或是 IoT 设备发送到 IoT 服务的遥测消息。如果你对数据库触发器database trigger不陌生可以把它类比为同一件事由“插入一行”之类的事件触发执行的代码。无服务器的关键特性与代价仅在事件发生时运行没有任何进程在事件之外“保活”你的代码。事件到来 → 代码加载 → 执行 → 结束。这使得扩展性极佳当大量事件同时到达时云厂商可以在可用服务器上并行运行任意多次你的函数实例无内存状态需要在多次事件之间共享信息时必须把状态存入数据库等外部存储而不能依赖进程内存以函数形式编写你的代码是一个函数以事件详情作为参数。Azure Functions 开箱即用地支持 Python、JavaScript、TypeScript、C#、F#、Java 和 PowerShell也支持自定义处理器custom handlers因此理论上可以用任何能处理 HTTP 请求的语言甚至 COBOL 这样的老语言编写函数名字里没有“无服务器”这件事其实是成立的无服务器背后仍有服务器只是作为开发者你不再关心服务器本身。云厂商的无服务器runtime负责分配服务器、网络、存储、CPU、内存等一切资源。因此计费不按“每台服务器”而是按代码运行时间 × 使用的内存量收取。有云厂商提供每月合计 100 万次执行免费额度超出后约每 100 万次 0.20 美元——代码不运行就不产生费用FaaS无服务器也称为 Functions as a Service因为每个事件触发器都以代码中的一个函数实现。对 IoT 开发者而言这个模型非常契合你编写一个函数它对连接到云端 IoT 服务的任意IoT 设备发来的消息做出响应——代码能处理所有消息却只在需要时运行。Functions app 的结构一个 Functions app 由一个或多个triggers触发器组成每个 trigger 就是一个响应事件的函数。一个 app 内可以有多个 trigger它们共享公共配置——例如在 app 的配置文件中放 IoT Hub 的连接信息app 内所有函数都能用它来连接并监听事件。二、创建无服务器应用安装工具链微软的无服务器计算服务叫Azure Functions。写 Azure Functions 的第一步是准备本地开发环境。适用前提提醒本课程写作时Azure Functions 工具链在 Apple Silicon 芯片 Mac 上对 Python 项目尚不完全可用需使用 Intel Mac、Windows PC 或 Linux PC。无服务器的一个重大优势是本地可运行与云端相同的 runtime 可以跑在本地计算机上你能编写响应 IoT 消息的代码并在本地运行、甚至调试确认无误后再部署上云。任务 1安装 Azure Functions 工具Azure Functions 工具是一个 CLI称为Azure Functions Core Tools。按照官方“Azure Functions Core Tools”文档安装核心工具在 VS Code 中安装Azure Functions 扩展它提供创建、调试和部署 Azure Functions 的支持。部署时Functions app 需要少量云存储来保存应用文件和日志本地运行时同样需要连接存储但可以用本地存储模拟器Azurite替代真实的云存储。Azurite 是一个 Node.js 应用在本地运行但表现得像云存储。补充一个 Azure 背景知识Azure Functions 使用的存储是Azure Storage Account一个账户可以同时存放文件、blob、表数据和队列数据并且可以在多个 app例如一个 Functions app 和一个 Web app之间共享。Azurite 的安装与启动步骤由于 Azurite 是 Node.js 应用先安装 Node.jsmacOS 上也可通过 Homebrew 安装安装 Azuritenpm随 Node.js 一起安装npm install -g azurite创建 Azurite 存放数据的目录mkdir azurite启动 Azurite 并指向该目录azurite --location azuriteAzurite 启动后输出如下表示本地 Functions runtime 可以连接➜ ~ azurite --location azurite Azurite Blob service is starting at http://127.0.0.1:10000 Azurite Blob service is successfully listening at http://127.0.0.1:10000 Azurite Queue service is starting at http://127.0.0.1:10001 Azurite Queue service is successfully listening at http://127.0.0.1:10001 Azurite Table service is starting at http://127.0.0.1:10002 Azurite Table service is successfully listening at http://127.0.0.1:10002任务 2创建 Azure Functions 项目Azure Functions CLI 用于创建新的 Functions app。创建并进入 Functions app 目录命名为soil-moisture-triggermkdir soil-moisture-trigger cd soil-moisture-trigger在该目录下创建 Python 虚拟环境python3 -m venv .venv激活虚拟环境Windows Command Prompt.venv\Scripts\activate.batWindows PowerShell.\.venv\Scripts\Activate.ps1macOS / Linuxsource ./.venv/bin/activate这些命令必须在创建虚拟环境时所在的目录中执行永远不需要cd进入.venv目录所有安装依赖、运行代码的命令都从创建虚拟环境的那个目录执行。初始化 Functions appfunc init --worker-runtime python soil-moisture-trigger这会在当前目录生成三个文件仓库中的参考实现同样具备这三个文件见 code/functions/soil-moisture-triggerhost.json—— Functions app 级别的设置 JSON 文档一般无需修改。参考仓库中的 host.json 可以看到它包含日志采样配置Application InsightsexcludedTypes: Request以及扩展程序包声明{ version: 2.0, logging: { applicationInsights: { samplingSettings: { isEnabled: true, excludedTypes: Request } } }, extensionBundle: { id: Microsoft.Azure.Functions.ExtensionBundle, version: [2.*, 3.0.0) } }从源码结构看extensionBundle的[2.*, 3.0.0)版本约束与az functionapp create --functions-version 3创建 v3 运行时相呼应用于让平台自动加载匹配版本的触发器扩展包。local.settings.json—— 本地运行时使用的设置例如 IoT Hub 连接字符串。仅本地使用不应提交到版本控制部署到云端后这些设置不会随 app 一起部署而是由 Application Settings 提供下文部署章节详述。参考仓库中的 local.settings.json{ IsEncrypted: false, Values: { FUNCTIONS_WORKER_RUNTIME: python, AzureWebJobsStorage: UseDevelopmentStoragetrue, IOT_HUB_CONNECTION_STRING: connection string, REGISTRY_MANAGER_CONNECTION_STRING: connection string } }requirements.txt—— Pip 依赖清单文件声明运行 Functions app 所需的包。仓库参考实现中的 requirements.txt 内容# Do not include azure-functions-worker as it may conflict with the Azure Functions platform azure-functions azure-iot-hub注意这条注释不要手动加入azure-functions-worker因为它由平台提供自行声明可能冲突。依赖必须写进此文件部署到云端时 runtime 才能确保安装正确的包。local.settings.json中有一个 Functions app 使用的存储账户设置默认为空需要填入以连接 Azurite 模拟器AzureWebJobsStorage: UseDevelopmentStoragetrue,安装 Pip 依赖pip install -r requirements.txt启动 Functions runtime 做验证func startruntime 启动后会报告未发现任何 job functiontrigger(.venv) ➜ soil-moisture-trigger func start Found Python version 3.9.1 (python3). Azure Functions Core Tools Core Tools Version: 3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0 (64-bit) Function Runtime Version: 3.0.15417.0 [2021-05-05T01:24:46.795Z] No job functions found.⚠️ 若弹出防火墙提示请允许func应用访问网络它需要读写网络若在 macOS 上看到/dev/shm/AzureFunctions共享内存目录的告警只要 app 能正常启动并列出函数即可忽略。按ctrlc停止 app。用 VS Code 打开当前目录可直接执行code .。VS Code 会检测出这是一个 Azure Functions 项目并弹出提示 “Detected an Azure Functions Project in folder soil-moisture-trigger ... Initialize for optimal use with VS Code?”选择Yes。确保 VS Code 终端中运行的是已激活的 Python 虚拟环境必要时先结束并重启终端。三、创建 IoT Hub 事件触发器Functions app 只是无服务器代码的“壳”。要响应 IoT Hub 事件需要给 app 加一个 trigger它连接到发送进 IoT Hub 的消息流并做出响应。获取这条消息流的方式是让 trigger 连接 IoT Hub 的event hub 兼容端点event hub compatible endpoint。原理背景IoT Hub 构建在另一个 Azure 服务Azure Event Hubs之上。Event Hubs 提供消息的发送与接收能力IoT Hub 在此之上扩展了面向 IoT 设备的功能。因此读取 IoT Hub 消息的连接方式与使用 Event Hubs 完全相同——Azure Functions 没有专门的 “IoT Hub trigger”用的就是Event Hub trigger。关于安全IoT 设备连接 IoT Hub 必须使用密钥保证只有被允许的设备能接入以读取消息的身份连接同理——你的代码需要一个包含密钥和 IoT Hub 信息的连接字符串。注意默认拿到的连接字符串带有iothubowner权限任何使用它的代码都对 IoT Hub 拥有完全权限。理想情况下应使用所需权限的最低级别本仓库后续的安全课程专门处理该问题。trigger 连接成功后函数内的代码会对发往 IoT Hub 的每一条消息被调用无论来自哪台设备消息作为参数传入。任务 1获取 event hub 兼容端点的连接字符串在 VS Code 终端执行将hub_name替换为你的 IoT Hub 名称az iot hub connection-string show --default-eventhub \ --output table \ --hub-name hub_name打开local.settings.json在Values节添加IOT_HUB_CONNECTION_STRING: connection string用上一步的值替换connection string并在该行后补逗号以保持 JSON 合法。任务 2创建事件触发器在soil-moisture-trigger目录内执行func new --name iot-hub-trigger --template Azure Event Hub trigger这会生成名为iot-hub-trigger的新函数并在soil-moisture-trigger下创建同名目录内含两个文件__init__.py—— 包含 trigger 的 Python 代码文件利用 Python 的包命名约定把该目录变成一个模块。模板生成的初始代码import logging import azure.functions as func def main(event: func.EventHubEvent): logging.info(Python EventHub trigger processed an event: %s, event.get_body().decode(utf-8))trigger 的核心是main函数——它会被 IoT Hub 事件调用。参数event是一个EventHubEvent每当有消息发到 IoT Hub该函数就被调用一次消息作为event传入同时携带与前一课看到的 MQTT 消息标注annotations相同的属性。初始代码的核心就是打印一条日志。function.json—— trigger 的配置文件主体是bindings节。Binding绑定是 Azure Functions 与其他 Azure 服务之间连接关系的术语。该函数有一个指向 event hub 的输入绑定连接到 event hub 并接收数据。当然也可以有输出绑定——例如加一个到数据库的输出绑定后把 IoT Hub 事件从函数返回就会被自动插入数据库。bindings中值得关注的值键值模板默认含义typeeventHubTrigger告诉函数监听 Event Hub 事件name与main函数参数名一致Event Hub 事件传入函数时使用的参数名必须与 Python 代码main(event)的参数名匹配directionin输入绑定数据从 event hub 流入函数connection设置项名称声明从哪个“设置”读取连接字符串本地运行时从local.settings.json读取安全设计连接字符串不能直接写在function.json里只能通过设置项间接引用——防止你不小心把密钥暴露进配置文件。对照仓库中的参考实现 function.json修正完成后的完整内容如下{ scriptFile: __init__.py, bindings: [ { type: eventHubTrigger, name: event, direction: in, eventHubName: , connection: IOT_HUB_CONNECTION_STRING, cardinality: one, consumerGroup: $Default, dataType: binary } ] }可以观察到模板生成的cardinality、eventHubName需要按下面三步修正而consumerGroup: $Default与dataType: binary保持模板默认即可consumerGroup即文档提示的“消费者组”机制多个 app 可用不同 consumer group 同时消费同一端点仓库后续课程有专门讲解。修正步骤由于 Azure Functions 模板存在已知缺陷模板仓库 issue #1250function.json中cardinality字段默认值错误需从many改为cardinality: one,把connection更新为指向你在local.settings.json中添加的设置项名称connection: IOT_HUB_CONNECTION_STRING,记住这里填的是设置项名称不是连接字符串本身。由于连接字符串中已包含eventHubName值function.json里对应字段需清空eventHubName: ,任务 3运行事件触发器确认没有同时运行 IoT Hub 事件监控程序前一课的服务器代码。若两者并行Functions app 无法连接并消费事件。运行 Functions appfunc startapp 启动后发现有iot-hub-trigger函数随后会处理最近一天内已发送到 IoT Hub 的事件(.venv) ➜ soil-moisture-trigger func start Found Python version 3.9.1 (python3). Azure Functions Core Tools Core Tools Version: 3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0 (64-bit) Function Runtime Version: 3.0.15417.0 Functions: iot-hub-trigger: eventHubTrigger For detailed output, run func with --verbose flag. [2021-05-05T02:44:07.517Z] Worker process started and initialized. [2021-05-05T02:44:09.202Z] Executing Functions.iot-hub-trigger (Reason(null), Id802803a5-eae9-4401-a1f4-176631456ce4) [2021-05-05T02:44:09.205Z] Trigger Details: PartitionId: 0, Offset: 1011240-1011632, EnqueueTimeUtc: 2021-05-04T19:04:04.2030000Z-2021-05-04T19:04:04.3900000Z, SequenceNumber: 2546-2547, Count: 2 [2021-05-05T02:44:09.352Z] Python EventHub trigger processed an event: {soil_moisture:628} [2021-05-05T02:44:09.354Z] Python EventHub trigger processed an event: {soil_moisture:624} [2021-05-05T02:44:09.395Z] Executed Functions.iot-hub-trigger (Succeeded, Id802803a5-eae9-4401-a1f4-176631456ce4, Duration245ms)每次函数调用都被Executing Functions.iot-hub-trigger/Executed Functions.iot-hub-trigger日志块包围从中可以看到每次调用处理了多少条消息上例为一次调用内 2 条。Trigger Details行暴露了底层 Event Hubs 的消费细节分区号PartitionId、偏移量Offset、入队时间、序列号——这正是 Event Hub 兼容端点按 Event Hubs 语义工作的直接证据。确保 IoT 设备在运行你会看到新的土壤湿度消息持续出现在 Functions app 输出中。停止并重启 Functions app它不会重复处理旧消息只处理新消息消费偏移被持久化本地由 Azurite 存储云端由 Storage Account 存储——这就是本地也需要“存储”的原因。VS Code 还支持直接调试函数点击行首边缘、Run - Toggle breakpoint或按F9设断点按F5、Run - Start debugging或运行调试面板的Start debugging按钮启动调试器即可查看正在处理的事件详情。故障排查若报错The listener for function Functions.iot-hub-trigger was unable to start. Microsoft.WindowsAzure.Storage: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused.检查 Azurite 是否在运行以及local.settings.json中AzureWebJobsStorage是否设为UseDevelopmentStoragetrue。若报错System.Private.CoreLib: Exception while executing function: Functions.iot-hub-trigger. System.Private.CoreLib: Result: Failure Exception: AttributeError: list object has no attribute get_body检查function.json中cardinality是否为one。该错误的机理cardinality为many时触发器把一批事件作为列表传入event.get_body()自然不存在。若报错Azure.Messaging.EventHubs: The path to an Event Hub may be specified as part of the connection string or as a separate value, but not both. Please verify that your connection string does not have the EntityPath token if you are passing an explicit Event Hub name. (Parameter connectionString).检查function.json中eventHubName是否已设为空字符串——事件 Hub 路径要么由连接字符串携带要么由eventHubName单独指定二者只能选其一。四、从服务器代码发送 Direct Method 请求到目前为止Functions app 只是通过 event hub 兼容端点监听消息。下一步是要向 IoT 设备发送命令这需要经Registry Manager建立另一条到 IoT Hub 的连接。Registry Manager 可以查看已注册设备、发送 cloud-to-device 消息、发送 Direct Method 请求、更新设备孪生以及注册、更新、删除设备。任务 1获取 Registry Manager 连接字符串执行hub_name替换为实际 Hub 名az iot hub connection-string show --policy-name service \ --output table \ --hub-name hub_name这里用--policy-name service请求的是ServiceConnect策略的连接字符串。申请连接字符串时可以选择其权限级别ServiceConnect 策略允许代码连接并向 IoT 设备发送消息——比 iothubowner 权限低得多体现了“最低权限”实践。在local.settings.json的Values节添加REGISTRY_MANAGER_CONNECTION_STRING: connection string任务 2向设备发送 Direct Method 请求Registry Manager 的 SDK 以 Pip 包形式提供在requirements.txt中加入见参考实现该文件最终为azure-functionsazure-iot-hub两行azure-iot-hub确保 VS Code 终端已激活虚拟环境安装依赖pip install -r requirements.txt在__init__.py顶部添加导入import json import os from azure.iot.hub import IoTHubRegistryManager from azure.iot.hub.models import CloudToDeviceMethod清空main方法体保留方法本身依次加入以下代码。第一步——解析事件提取消息体与设备 IDbody json.loads(event.get_body().decode(utf-8)) device_id event.iothub_metadata[connection-device-id] logging.info(fReceived message: {body} from {device_id})event.get_body()是设备发来的遥测 JSON如{soil_moisture:628}iothub_metadata字典由 IoT Hub 自动附加包含发送者设备 ID、消息时间等属性。第二步——根据湿度阈值构造 Direct Method 请求soil_moisture body[soil_moisture] if soil_moisture 450: direct_method CloudToDeviceMethod(method_namerelay_on, payload{}) else: direct_method CloudToDeviceMethod(method_namerelay_off, payload{})代码读取遥测中的soil_moisture值超过阈值 450 时构造relay_on请求否则构造relay_off。方法请求本身不需要有效载荷因此发送空 JSON 文档{}。这两个方法名正对应前几课中设备端 Arduino 固件注册的可调用方法。第三步——从环境读取连接字符串并创建 Registry Manager 实例logging.info(fSending direct method request for {direct_method.method_name} for device {device_id}) registry_manager_connection_string os.environ[REGISTRY_MANAGER_CONNECTION_STRING] registry_manager IoTHubRegistryManager(registry_manager_connection_string)local.settings.json中的值会被本地 runtime 注入为环境变量通过os.environ返回所有环境变量的字典读取。部署到云端后这些值将以Application Settings的形式存在同样可从环境变量读取——本地与云端的代码完全一致这正是配置外部化设计的好处。第四步——向“发送这条遥测的那台设备”下发指令registry_manager.invoke_device_method(device_id, direct_method) logging.info(Direct method request sent!)完整实现见仓库参考文件 iot-hub-trigger/init.py与上述分段拼合后完全一致。与早期 MQTT 版本的关键差异此前用 MQTT 主题控制继电器时控制命令会广播给所有设备代码假设只有一台设备。现在 Direct Method 请求被定向到单一设备device_id来自事件的connection-device-id因此即使部署多套“湿度传感器 继电器”装置每条指令也只发给正确的设备。运行 Functions app确保 IoT 设备在发送数据终端会显示消息被处理、Direct Method 请求被发出把土壤湿度传感器反复插入/拔出土壤可以看到数值变化、继电器随之通断。五、把无服务器代码部署到云端代码已在本地跑通下一步是把 Functions App 部署上云。任务 1创建云资源Functions App 需部署到 Azure 中的 Function App 资源放在为 IoT Hub 创建的资源组里同时需要一个真正的 Storage Account 替代本地的 Azurite 模拟器。创建存储账户az storage account create --resource-group soil-moisture-sensor \ --sku Standard_LRS \ --name storage_namestorage_name必须全局唯一它是访问 URL 的一部分只能用小写字母和数字最长 24 字符。建议用sms之类的前缀加一个唯一后缀随机词或你的名字--sku Standard_LRS选择最低价的标准通用层本地冗余。存储没有免费层按用量付费成本相对很低最贵的存储类型也低于每月每 GB 0.05 美元。创建 Function Appaz functionapp create --resource-group soil-moisture-sensor \ --runtime python \ --functions-version 3 \ --os-type Linux \ --consumption-plan-location location \ --storage-account storage_name \ --name functions_app_name各参数说明location创建资源组时使用的同一位置storage_name上一步创建的存储账户名functions_app_name全局唯一的函数应用名也是 URL 的一部分建议soil-moisture-sensor-前缀加唯一后缀--functions-version 3选用 Azure Functions 第 3 版运行时本课程写作时的最新版与本地host.json中扩展包版本约束[2.*, 3.0.0)兼容--os-type LinuxFunctions 可托管在 Linux 或 Windows 上视语言而定——Python 应用仅支持 Linux--consumption-plan-location采用 Consumption按量计费计划与该课“按执行次数和运行时长计费”的无服务器理念一致。任务 2上传应用设置开发期间IoT Hub 连接字符串存在local.settings.json中上云前必须把它们写入 Function App 的Application Settings代码才能取到。概念对照local.settings.json仅用于本地开发不应提交到 Git 等源码控制云端使用 Application Settings——一组托管在云端的键/值对由 runtime 或你的代码以环境变量的形式读取。本地与云端由此实现“同一份代码、不同配置来源”。设置IOT_HUB_CONNECTION_STRINGaz functionapp config appsettings set --resource-group soil-moisture-sensor \ --name functions_app_name \ --settings IOT_HUB_CONNECTION_STRINGconnection string其中connection string取local.settings.json中同名键的值。重复上一步把REGISTRY_MANAGER_CONNECTION_STRING设为local.settings.json中的对应值。执行这些命令时Azure CLI 还会回显该 Function App 的全部Application Settings可借此核对值是否正确。注意你会看到AzureWebJobsStorage已有值本地它指向 Azurite 模拟器而云端在创建 Function App 时传入--storage-account参数后平台已自动把它写好了。任务 3发布 Functions Appfunc azure functionapp publish functions_app_name代码会被打包并发送到 Function App在那里部署并启动。控制台输出量较大结尾是部署确认与已部署函数清单——本例只有那个 triggerDeployment successful. Remote build succeeded! Syncing triggers... Functions in soil-moisture-sensor: iot-hub-trigger - [eventHubTrigger]确认 IoT 设备在运行通过调节土壤湿度或把传感器插入/拔出土壤来改变湿度水平继电器会随之自动通断。至此控制继电器时机的“服务器代码”已完全从你的电脑移到了云端设备上报遥测 → Event Hub 兼容端点 → Azure Functions 触发 → Registry Manager 下发 Direct Method → 设备执行。六、思考题与课后作业思考挑战在前一课中你用“继电器开启期间退订 MQTT 消息、关闭后短暂继续退订”的手法来控制继电器通断节奏。这套办法在无服务器场景不可用——你无法让 IoT Hub trigger “退订”。请思考在 Functions App 中可以用哪些方式处理同样的时序控制需求提示方向利用iothub_metadata中的时间戳做状态判断、引入外部存储记录上次操作时间等均需借助前文所述“无服务器没有内存状态”的特性来设计。课后作业——添加手动继电器控制详见 assignment.md无服务器代码可以被很多事物触发HTTP 请求即是其一。作业要求给 Functions App 添加两个 HTTP triggerrelay_on/relay_off复用本课学到的 Direct Method 发送逻辑实现通过 Web 请求手动开关继电器。作业给出的关键提示创建 HTTP triggerfunc new --name trigger name --template HTTP triggerHTTP trigger 默认需要函数专属 API 键访问控制若想让任何人可调用把该 trigger 的function.json中authLevel改为anonymous生产环境不建议这样做HTTP trigger 默认同时支持 GET 与 POST本地运行时可在终端看到 URL形如http://localhost:7071/api/relay_on直接用浏览器打开即可触发部署后 URL 形如https://functions app name.azurewebsites.net/api/trigger name注意 HTTP trigger 默认挂在api子路径下。七、小结本课建立的云侧控制链路环节机制关键配置/代码事件来源IoT 设备遥测进入 IoT Hub设备侧沿用前一课的 MQTT 上报事件消费Event Hub 兼容端点 Event Hub triggerfunction.json中eventHubTrigger绑定、cardinality: one、eventHubName: 本地存储Azurite 模拟 Storage AccountAzureWebJobsStorage: UseDevelopmentStoragetrue指令下发Registry Manager Direct Methodazure-iot-hub包、invoke_device_method(device_id, ...)凭据管理连接字符串只存设置项经环境变量读取local.settings.json→ 云端 Application Settings部署func azure functionapp publishConsumption 计划、Python 3 运行时、Linux参考实现的完整代码可在 code/functions 目录逐文件对照英文原版课程文档含更多研究链接与视频见 2-farm/lessons/5-migrate-application-to-the-cloud/README.md后续课程存储位置数据、安全加固等可参考 docs/_sidebar.md 中的课程目录继续学习。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表