2. AWS IoT Core 核心概念与接入模型

在 AWS IoT Core 中,设备接入并不是“把设备连上网络”这么简单。一个设备从物理世界进入云端,需要同时回答四个问题:它是谁(身份)、它被允许做什么(授权)、它如何与云端交换数据(通信)、云端如何管理它的状态与行为(管理)。AWS IoT Core 用一组相互配合的核心对象来回答这些问题:Thing、Thing Type、Thing Group、证书、策略、MQTT 主题、设备影子、任务。理解它们之间的层次与引用关系,是后续所有接入工程的基础。

一、身份层:Thing、Thing Type 与 Thing Group

Thing(事物)是 AWS IoT Core 中设备的逻辑表示,可以理解为设备在云端的“档案”。它本身不包含连接能力,而是一个命名实体,通常用名称或 ARN 标识。例如一台温度传感器在云端注册为 Thing,名称为 sensor-plant-a-001。Thing 可以携带属性(Attribute),如 model=TH-200、location=plant-a,这些属性是静态元数据,用于检索和分组,不参与运行时状态。

Thing Type(事物类型)是对同类设备的抽象模板。它把一组设备共有的属性定义集中起来,避免每个 Thing 重复填写。例如定义 ThingType: TemperatureSensor,包含 manufacturer、model、firmwareVersion 三个属性。创建 Thing 时指定该类型,即可继承这些属性字段。Thing Type 还支持“弃用”标记,便于版本演进。

Thing Group(事物组)是设备的逻辑集合,支持层级嵌套。它有两个关键作用:一是批量管理,例如对整组设备下发任务;二是策略继承,组上附加的策略会作用于组内所有 Thing。典型结构如:AllDevices → PlantA → TemperatureSensors,一台设备可以同时属于多个组,从而叠加多组策略。

二、安全层:证书与策略

设备与 AWS IoT Core 之间的连接必须经过双向 TLS 认证。设备侧持有 X.509 证书和私钥,AWS IoT Core 侧持有对应的 CA 证书。证书在 AWS IoT Core 中注册并激活后,才具备连接资格。证书可以附加到 Thing 上,也可以独立存在;附加到 Thing 后,证书与设备身份形成绑定关系。

策略(Policy)是 JSON 文档,定义“谁可以对哪些资源执行哪些操作”。它不绑定设备,而是绑定证书或 Cognito 身份。策略的核心字段包括 Effect(Allow/Deny)、Action(如 iot:Connect、iot:Publish、iot:Subscribe、iot:Receive)、Resource(主题或主题过滤器)以及可选的 Condition。例如,只允许设备发布到自己的主题:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:cn-north-1:123456789012:client/sensor-plant-a-001"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:cn-north-1:123456789012:topic/sensors/plant-a/001/data"
    }
  ]
}

策略遵循“默认拒绝”原则:没有显式 Allow 的操作一律拒绝。多个策略叠加时,只要有一个 Allow 且没有 Deny,即允许。这一点与 IAM 策略一致,是排查连接失败时最常检查的对象。

三、通信层:MQTT 主题

MQTT 是 AWS IoT Core 的主要通信协议,采用发布/订阅模型。设备通过 主题(Topic) 发布消息,其他客户端通过订阅主题接收消息。主题是分层字符串,用 / 分隔,例如 sensors/plant-a/001/data。AWS IoT Core 支持通配符:+ 匹配单层,# 匹配多层。订阅 sensors/plant-a/+/data 可以接收该厂区所有设备的数据。

主题设计直接影响权限粒度、消息路由和成本。常见约定包括:dt/<device-id>/data 用于遥测,cmd/<device-id>/set 用于下行命令,$aws/things/<thing-name>/shadow/update 用于设备影子交互。主题本身不持久化,消息到达时若无人订阅即被丢弃(除非配置了规则引擎转发到其他服务)。

四、管理层:设备影子与任务

设备影子(Device Shadow)是设备状态的云端 JSON 文档,即使设备离线也可读写。它包含三个部分:desired(期望状态)、reported(设备上报状态)、delta(两者差异)。设备上线后订阅 $aws/things/<thing-name>/shadow/update/delta,收到差异后执行动作,再通过 update 上报新的 reported,形成闭环。影子适合“设置目标温度”“开关灯”这类状态同步场景。

任务(Job)用于对一组设备下发远程操作,例如固件升级、重启、配置变更。Job 文档描述操作内容,可指定目标设备组、超时时间、重试策略和滚动执行速率。设备端通过 $aws/things/<thing-name>/jobs/notify-next 获取待执行任务,执行后上报状态。Job 与影子的区别在于:影子关注“状态同步”,Job 关注“动作执行与进度跟踪”。

AWS IoT Core 设备接入核心对象关系图 身份层 Thing sensor-plant-a-001 设备云端档案 Thing Type TemperatureSensor 同类设备属性模板 Thing Group PlantA/TempSensors 批量管理与策略继承 属于 加入 安全层 X.509 证书 双向 TLS 身份凭证 注册并激活后可用 策略 Policy Connect / Publish / Subscribe 默认拒绝,显式 Allow 策略绑定 证书 / Cognito 身份 多策略叠加生效 附加 绑定 通信层 MQTT 主题 sensors/plant-a/001/data cmd/plant-a/001/set 通配符 + 单层,# 多层 发布/订阅,不持久化 管理层 设备影子 desired reported delta 差异 离线可读写 任务 Job 固件升级 / 重启 目标设备组 超时与重试 滚动执行速率 绑定 授权 策略继承 状态同步 动作下发 身份层定义“是谁”,安全层定义“能做什么”,通信层定义“怎么传”,管理层定义“怎么管”

五、对象之间的引用关系与工程含义

这些对象并非孤立存在,而是通过引用形成一张关系网。一台设备接入的典型链路是:创建 Thing 并指定 Thing Type,将 Thing 加入 Thing Group;为设备生成 X.509 证书,将证书附加到 Thing;创建 Policy 并绑定到证书;设备使用证书连接后,按策略允许的主题发布/订阅;云端通过 Device Shadow 同步状态,通过 Job 下发操作。

理解这张关系图对排障尤其重要。例如设备连接被拒绝,可能的原因依次是:证书未激活、证书未附加到 Thing、策略未绑定、策略中缺少 iot:Connect 或 Resource 不匹配。设备能连接但收不到消息,则要检查订阅主题是否在策略的 iot:Subscribe 和 iot:Receive 允许范围内。设备影子更新无响应,要确认设备是否订阅了 delta 主题,以及策略是否允许发布到 shadow/update。

实践建议:在批量接入前,先用一台设备走通“Thing + 证书 + 策略 + 主题 + 影子”的最小闭环,确认策略 Resource 的 ARN 格式正确(注意区域、账号、主题路径三者一致),再复制到 Thing Group 和 Job 的批量流程中。策略中尽量使用具体主题而非 # 通配,避免权限过宽。

六、最小接入配置示例

下面给出一个可参考的最小策略与主题约定,用于单台温度传感器上报数据并接收目标温度设置。示例中的区域、账号和 Thing 名称均为占位值,实际使用时需替换。

# 主题约定
上行遥测: sensors/plant-a/001/data
下行命令: cmd/plant-a/001/set
影子更新: $aws/things/sensor-plant-a-001/shadow/update
影子差异: $aws/things/sensor-plant-a-001/shadow/update/delta

# 策略要点
iot:Connect    → client/sensor-plant-a-001
iot:Publish    → topic/sensors/plant-a/001/data
iot:Subscribe  → topicfilter/cmd/plant-a/001/set
iot:Receive    → topic/cmd/plant-a/001/set
iot:Publish    → topic/$aws/things/sensor-plant-a-001/shadow/update
iot:Subscribe  → topicfilter/$aws/things/sensor-plant-a-001/shadow/update/delta
iot:Receive    → topic/$aws/things/sensor-plant-a-001/shadow/update/delta