• MQTT 学习笔记


    MQTT特点

    MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议。

    1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合

    2、对负载内容屏蔽的消息传输。

    3、使用TCP/IP提供网络连接:

    主流的MQTT是基于TCP连接进行数据推送的,但是同样有基于UDP的版本,叫做MQTT-SN。这两种版本由于基于不同的连接方式,优缺点自然也就各有不同了

    4、有三种消息发布服务质量:

    [1] “至多一次”,消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复:

    这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。

    [2] “至少一次”,确保消息到达,但消息重复可能会发生:

    这一种方式比较鸡肋,在我的想象中没能想到这种质量的发送在常规的APP开发中有什么用处。

    [3] “只有一次”,确保消息到达一次:

    这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。

    5、小型传输,开销很小(固定长度的头部是2字节),协议交换最小化,以降低网络流量:
    这就是为什么在介绍里说它非常适合“在物联网领域,传感器与服务器的通信,信息的收集”,要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了。
     

    6、使用Last Will和Testament特性通知有关各方客户端异常中断的机制:

    Last Will:即遗言机制,用于通知同一主题下的其他设备发送遗言的设备已经断开了连接。

    Testament:遗嘱机制,功能类似于Last Will 。

     

    由于MQTT 协议具有开放、简单、轻量、易于实
    现等优点, 因此他特别适用于低带宽, 网络不稳定,
    网络代价昂贵以及处理器和存储器资源有限的嵌入式
    设备和移动终端上.

    术语:

    客户端(Client):
    使用MQTT的程序或设备。客户端总是通过网络连接到服务端。它可以

    • 发布应用消息给其它相关的客户端。.
    • 订阅以请求接受相关的应用消息
    • 取消订阅以移除接受应用消息的请求。
    • 从服务端断开连接。

    服务端(Server):

    一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介。服务端

    • 接受来自客户端的网络连接
    • 接受客户端发布的应用消息
    • 处理客户端的订阅和取消订阅请求
    • 转发应用消息给符合条件的客户端订阅

    订阅(Subscription):

    订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。

    主题名(Topic Name):

    附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。

    主题过滤器(Topic Filter:):

    订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。

    会话(Session):

    客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。

    控制报文(MQTT Control Packet):

    通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个(PUBLISH报文)用于传输应用消息。

     

    系统框架设计

    整个服务器部分主要分成三个层次. 第一层是
    MQTT 消息推送broker, 负责完成协议底层的网络通
    信机制以及针对各种不同类型消息的收发机制; 第二

    层由身份验证模块、ACL 控制模块、自动订阅模块、
    话题统计模块以及状态监控模块组成, 是在底层通信
    机制的基础上完善整个系统实际应用中所需的各项功
    能; 第三层是数据存储层, 为第二层的各个模块提供
    数据的支持, 用于各项数据的统计与交互. 整个系统
    框架如图1 所示.

    各模块的设计与实现

    消息推送中间件

    目前在各种平台上对于MQTT协议有许多不同的
    实现, 这里所选择的Mosquitto 是一款开源的基于C实
    现的MQTT server/broker, 比较完整的实现了MQTT
    协议中要求的各项基本功能, 可以在Windows, Linux
    以及其它类Unix 系统中编译运行.

    数据存储层

    在数据存储层中, 有的数据是需要经常读取的,
    比如用户的名称、密码、ID 以及用户间的好友关系等;
    有的数据是需要经常写入和修改的, 比如某些话题的
    订阅数; 有的数据是不经常读取或写入的, 比如服务
    器的运行状态. 为了提高效率, 对于需要经常读取或
    写入的与用户相关的数据, 用Redis 数据库存储, 对于
    不经常读取或写入的与服务器状态相关的数据, 用
    MYSQL 数据库存储.

    这里的Redis 是一个基于key-value 的开源no-sql
    数据库, 它将数据缓存在内存中, 相对于传统的关系
    型数据库来说, 性能上有很大提高, 特别适用于对访
    问速度和并发性要求比较高的情况[6,7]. 同时Redis 也
    支持数据的持久化, 并且支持list, set, hash 等多种不同
    的数据结构. 在这里采用Redis 来存储每个用户的用
    户名密码等相关信息和与话题有关的数量统计, 以处理大并发量下的用户访问请求.

    密码验证模块

    在客户端向服务器发起连接请求的时候, 服务器
    必须对其进行密码验证, 以决定是否接受该连接请求,
    验证过程如图2 所示.

    为了增加数据库的安全性, 在用户注册时需要对其
    密码加密后再将其密文存入数据库, 这样即使有人利用
    非法手段侵入数据库, 也无法得到用户的真实密码. 在
    这里采用的MD5 加密算法是一种散列加密算法[8], 任何
    一个密码经过MD5 的HASH 散列计算之后将会产生一
    个128bit 的序列. 但是缺点是两个相同的密码会产生相
    同的散列, 为了弥补这个不足, 需要引入SALT 技术[9],
    在用户注册时生成一个随机数据, 与用户密码一起进行
    散列计算, 然后将得到的密文和SALT 值一起存入数据
    库中, 这样就可以保证即使用户的密码相同, 只要随机
    的SALT 值不同, 其密文就不相同.
    在用户发起连接请求时, 将用户提交的密码明文
    与数据库中的SALT 值一起进行散列计算, 将所得密文
    与数据库中密文进行比对即可对用户密码进行验证.

    ACL 控制模块

    为了规范用户行为, 需要对其话题的订阅和发布
    进行权限控制. ACL(Access Control List)又称为访问控
    制列表, 是一种通过匹配关系对访问权限进行控制,
    以加强系统安全性的技术[10,11].
    ACL 表采用的格式为:
    user <username>
    [read/write] <topic>
    或者

    pattern [read/write] <topic>
    第一种格式为特定用户的权限控制规则, 第二种
    格式为所有用户的权限控制规则, read 表示具有订阅
    的权限, write 表示具有发布的权限, topic 采用层级结
    构组织, 检查的时候从左至右各层依次进行匹配.
    ACL 表赋予用户应该具有的最小权限, 只要满足表中
    的一项, 即表示验证通过.
    为了满足移动社交网络中的应用需求, 需要引入
    通配符来表示用户之间的关系, 在这里, 用%u 表示用
    户自身的用户名, %c 表示用户自身的ID 号, %f 表示用
    户的单向关注的关系, %F 表示用户互相关注的关系
    (这里我们称之为好友), +表示话题中单层的通配, #表
    示话题中若干层的通配, 一个典型的ACL 表项为:
    pattern read user/%F/presence/+
    该规则表示该用户对所有他的好友的presence 之
    下的一级子话题具有订阅的权限.

    自动订阅模块

    在系统的实际应用中, 用户需要接收各种各样的
    推送话题, 例如系统的广播通知、好友的上线提醒、好
    友发送的即时消息等, 如果每次上线的时候都由客户
    端来对这些话题进行订阅, 不但会影响客户端的性能,
    还会占用移动终端的网络资源, 尤其是在用户关系复
    杂, 需要订阅大量话题的时候. 因此, 服务器可以在用
    户登录成功之后为用户自动订阅这些话题, 以减少网
    络上的数据交互. 自动订阅模块流程如图3 所示.

    自动订阅支持ACL 控制模块中提到的各项通配
    符, 并且将%u 替换为自身用户名, %c 替换为自身ID,
    含有%f 和%F 的表项会被通配为多个话题分别进行自
    动订阅. 一个典型的自动订阅表项为:
    user/%F/presence/+ 1
    表示每个用户上线时都会自动订阅其好友的
    presence之下一级的话题, QoS设为1, 中间以空格分隔.

    话题统计模块

    当大量用户在一段时间内同时订阅某一话题, 或
    者向某一话题发布消息时, 意味着这个话题是当前用
    户所关注的热点. 因此, 对话题的统计有助于分析用
    户群体的行为方式以及当前社会生活中的热点时事,
    对于发掘用户的潜在需求有重要的意义.
    为了提高消息推动服务器的性能, 话题的统计数
    据记录在redis 数据库中, 以topic-count 的形式存储,
    当用户在统计的话题上进行订阅或者发布的时候, 服
    务器调用Redis 的INCR 或DECR 命令对统计数据进
    行更新.

    状态监控模块

    要确保服务器长时间稳定的运行, 需要定期对系
    统运行的状态进行监控. 一方面要监控服务器本身的
    系统信息, 如CPU 占用率、内存占用率、磁盘剩余空
    间大小、网络流量等等, 这些数据在linux 环境下可以
    通过解析/proc 下相关文件的内容来获取; 另一方面需
    要监控消息推送服务的运行状况, 如活跃的用户数、
    用户订阅话题的总数等. Mosquitto 提供了对这些信息
    进行统计的机制, 所得的数据将由服务器以话题的形
    式定期进行发布, 监控模块需要以客户的身份登录并
    订阅相应话题以获取相关信息, 采集到的结果插入到
    MYSQL 数据库中, 以供服务器进行性能分析以预警.

  • 相关阅读:
    jQuery选择器总结
    HTML页面跳转的5种方法
    与孩子共情就是这么简单!
    C#中使用OracleTransaction
    如何查看Mysql服务器上的版本
    使用C#通过Oracle.DataAccess连接Oracle,部署时需要注意版本问题
    使用docker搭建hadoop环境,并配置伪分布式模式
    Hadoop安装教程【转】
    PHP+Hadoop+Hive+Thrift+Mysql实现数据统计分析
    《阿里巴巴 Java 开发手册》划重点!
  • 原文地址:https://www.cnblogs.com/saryli/p/9748095.html
Copyright © 2020-2023  润新知