简介
AWS IoT Core是什么?
先看下官方描述以及图示,
- AWS IoT 提供将您的物联网设备连接到其他设备和 AWS 云服务的云服务。
由上述可知,AWS IoT,Internet of Things,让设备接入网络后,即可进行与云端服务的通信,实现设备与云端服务的通信,或设备与设备之间的通信。那么其实现是基于什么的呢?答案是MQTT协议。
为什么用MQTT?
包括AWS IoT Core,阿里云等各大厂商(【1分钟速览!ioT服务厂商】) 大体都是基于MQTT协议进行的IoT服务实现。
为什么这些厂商会选择MQTT协议?(【Hello, ioT! 车企巨头在ioT中的实践】),
总结来讲,有2点
- 质量保障:MQTT协议中有明确的服务质量定义,基于此实现的服务,可以让不稳定网络环境下的数据传输,变的更加可靠。
- 场景符合:基于MQTT协议实现的IoT服务,不仅提供高可靠的通信服务,还有心跳机制、遗嘱消息、离线消息和安全管理等功能,非常契合物联网,数据回传,指令下发的场景。
典型图示
MQTT的基本模式是 发布/订阅模式,如上图,
- publish: 发布者指定消息发布的主题,将消息publish到MQTT Broker上(AWS等厂商提供的服务)。
- subscrib: 订阅者通过订阅相应的主题,向MQTT Broker注册对该主题的订阅,当有新的消息发布到该主题时,MQTT Broker会将消息发送给所有订阅了该主题的订阅者。
重要概念
由于IoT服务是基于MQTT协议的,在开始演示示例之前,先介绍下MQTT里面一些重要概念,以及在AWS IoT Core里面的一些细节。
服务质量保障QoS
MQTT设计了一套保证消息稳定传输的机制,包括消息应答、存储和重传。
在这套机制下,提供了三种不同层次QoS(Quality of Service):
- QoS0,At most once,至多一次;发送端只传一次,不保证消息一定送达到接收端。
- QoS1,At least once,至少一次;发送端至少发一次,确保接收端收到。
- QoS2,Exactly once,确保只有一次;确保接收端收到且只收到一次。
注意很多服务厂商,包括AWS IoT Core都没有支持QoS2。但是我们可以使用QoS1 ,然后在业务接收端接收的时候,通过业务id去重,实现幂等性,以此达到和QoS2相同的效果。
持久性会话 - Persistent Session
持久性会话存储客户端尚未确认的服务质量(QoS)为 1 的客户端的订阅和消息,当设备重新连接到持久性会话时,该会话恢复,订阅恢复,并将在重新连接之前接收和存储的未确认的订阅消息发送到客户端。
再继续介绍之前,让我们再仔细想下这个session有什么用 或者 怎么起作用的?
假设我们有个场景是 ,车上有数据需要传给手机,但是手机因为网络不稳定,中间网络断了一会儿,恰好断开到恢复之间,车上有数据发出。此时依靠持久性会话Persistent Session,手机网络恢复重新连接后,可收到刚刚断网期间没有收到的消息。
图示 :
上图所示3个阶段,
1,手机端以mqtt client身份(clientId - iphone01 )连到mqtt broker,产生一个persistent session。
2,手机端断网,断网期间,车上有数据传回,先传到mqtt broker的队列里,但此时由于手机端断网无法接收。
3,手机端网络恢复,继续以mqtt client(clientId - iphone01 )连到mqtt broker,此时broker会判断persistent session是否还在,如果还在的话 (没有过期 并且 客户端重连时没主动清除),则可把刚刚没传到的消息,继续推给 clientId - iphone01的设备。
由此,对于使用移动端网络在室外不断活动的情况,拿着手机移动,网络不稳定,一会断一会儿恢复,依靠persistent session,断开这段时间内的数据并不会丢弃,先存在队列里,当网络恢复时,可在通过persistent session找到之前设备的订阅情况,再进行推送。
相关的2个重要的相关参数 ,
Clean Session
- 当其为false时,表示创建一个持久会话,客户端断开连接后,broker仍会保持session(直到会话超时注销),如果在未过期时间内,相同client id的设备再次上线,broker还是会将断开时间内的信息发给这个设备。
- 当其为true时,代表相同client id的设备再次上线后,会主动和server说 ,重新创建一个session,这样之前的session就会清空,这段时间内尚未发给客户端的消息也会直接清空,不再发给这个设备。
Session Expiry Interval
指定客户端断开后多久,服务端认为session过期。 如果设置为 0,则 session 会在 client 离线时被立刻删除,最大可以设置为 UINT_MAX(4,294,967,295)。
注意: 除了上述MQTT协议的定义,实际各个厂商在实现上,超过限制数量的消息也将被删除,毕竟存储空间有成本,不能无限提供,以aws IoT core举例,其一些具体规则如下,
-
根据账户限制存储消息。超过限制的消息将被删除。有关持久消息限制的更多信息,请参阅 AWS IoT Core 终端节点和配额。
-
当客户端重新连接到其持久性会话时,将恢复所有订阅,并以每秒 10 条消息的最大速率将所有已存储消息发送到客户端。
-
结束持久性会话
- 在 MQTT 3 中,持久性会话过期时间的默认值为一小时,此设置适用于账户中的所有会话。
- 在 MQTT 5 中,您可以为 CONNECT 和 DISCONNECT 数据包上的每个会话设置会话过期间隔。
主题 - Topic
自定义主题
MQTT中 ,数据传递都是通过pub/sub 不同主题topic进行的。使用者可以自定义主题topic,以此来进行数据传递。此外,在各个厂商实现的时候,会对预留一些特殊的topic。以下拿aws IoT core举例,
aws 预设的主题
包括事件,规则等,以此来用于监控 一些设备情况(订阅情况等)。
还有些是为了aws IoT core上的其它功能比如任务, 影子等预留的主题,方便这些功能的使用和监控。
具体:https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/reserved-topics.html
保留消息
介绍:客户端订阅主题后,MQTT 保留消息会被发送给客户端。如果希望所有订阅主题的客户端在订阅后立即收到 MQTT 保留的消息,则可以发布设置了 RETAIN 标志的配置消息。只要发布新的配置消息,订阅客户端也会收到该配置更新。
AWS IoT Core上的实践:保存设置了 RETAIN 标志的 MQTT 消息。这些 保留消息 被作为普通的 MQTT 消息发送给已订阅该主题的所有客户端,同时也被存储起来发送给该主题的新订阅者。
更新保留消息:每个主题名称只保留一条消息。发布到主题的带有 RETAIN 标志设置的新消息将替换先前发送到该主题的任何现有保留消息。
典型示例:
作为初始配置消息
客户端订阅主题后,MQTT 保留消息会被发送给客户端。如果您希望所有订阅主题的客户端在订阅后立即收到 MQTT 保留的消息,则可以发布设置了 RETAIN 标志的配置消息。只要发布新的配置消息,订阅客户端也会收到该配置更新。
作为状态消息
设备可以在当前状态消息上设置 REATIN 标志,以便 AWS IoT Core 保存它们。当应用程序连接或重新连接时,它们可以订阅此主题,并在订阅保留的消息主题后立即获得上次报告的状态。这样,它们就不必等到设备发出下一条消息才能看到当前状态。
遗嘱 Will , MQTT Last Will and Testament(LWT)消息
MQTT协议里这个概念,很形象的比喻 ,大意就是如果MQTT client意外断开连接,挂了,broker会代替它发最后一条消息给订阅者。
broker将存储 Will 消息,直到出现断开连接。发生这种情况时,broker将向所有订阅 Will 主题的客户端发布消息以通知断开连接。如果客户端使用 MQTT DISCONNECT 消息通过客户端启动的断开连接来断开与代理的连接,则代理不会发布存储的 LWT 消息。在所有其它情况下,将分派 LWT 消息。
简单总结一下:客户端被动断开时(意外)会发Will,客户端主动断开时 ,不会发Will。
共享订阅
AWS IoT Core 支持 MQTT 3 和 MQTT 5 的共享订阅。共享订阅允许多个客户端共享对某个主题的订阅,并且只有一个客户端会收到使用随机分布发布到该主题的消息,从而实现负载均衡,可参考图示:
共享订阅流程
对比普通订阅,非共享订阅流程,图示:
非共享订阅流程
客户端连接鉴权
AWS IoT支持3种,分别是 证书,IAM用户角色,Amazon Cognito身份。这里大致总结下这三种的特点,
证书:
- 可以直接在AWS上生成 ,默认由AWS上的CA生成,也可以向AWS上注册自己的证书颁发机构 (CA),签署自定义证书。
- 证书生成时选择对应的权限角色 。
- 证书有有效期。
IAM用户角色:选择权限角色后,会生成固定的access key和secret key,然后客户端使用access key加secret key进行服务端的连接鉴权。
Amazon Cognito身份: 这个的灵活度就很大了,支持自定义账户密码,或者还可以外接其他账户进行鉴权(例如 Login with Amazon、Facebook 和 Google)
演示
这里我们客户端连接服务broker时,采用证书进行服务连接时的鉴权。
在AWS上生成一个物品(Thing)
1)进入到AWS IoT Core控制台,创建一个物品,
这里先只填物品名称即可,设备影子可以先不选,这个功能后续会单独讲解,此处不展开。
- 这里我们先选自动生成新证书,让AWS帮我们生成证书。
3)添加策略到证书,也就是赋予这个证书什么样的权限,从而让使用这个证书的设备端获得什么样的权限,这里如果没有策略可以先创建一个策略。
进入到创建策略页面后,可以细分权限, 比如发布端只赋予发布权限,接收端只赋予接收权限,如果不严格或者测试使用,可以直接选*全部。
使用创建好的策略 ,添加到证书上。我这里有个之前创建好的策略,trusted_device 信任设备,拥有发布订阅权限。
随后会进入到这个页面,生成证书和密钥 ,这里都要下载,红框中的三个是在下文demo中用到的文件。
.pem.crt是客户端证书(里面也含有客户端公钥), -private.pem.key是客户端私钥,然后是根CA 。
演示Pub - Sub
按上述操作,我们可以分别生成2个物品Thing,进行Pub - Sub的演示,这里使用Python SDK进行演示,
发送端:
接收端:
代码地址:https://github.com/Wunan777/aws_iot_demo/tree/main
结语
至此我们完成了 对于 AWS IoT Core重要概念的讲解,以及Demo实践。
相较于其它厂商,AWS IoT Core 除了实现了基础的MQTT功能,还有额外的比如影子,任务等功能,其对于IoT的实现是丰富,成熟的,推荐大家了解,这也对深入理解IoT设计有一定启发和帮助!