梁 晓,龙 妍,张 川
(1.广西开放大学,广西 南宁 530022;2.南宁职业技术学院,广西 南宁 530008;3.广西衡安睿建数字科技有限公司,广西 南宁 530021)
近些年随着物联网(Internet of Things,简称IoT)技术的发展,物联网产品的种类日益丰富,应用也越发普及,给人们工作和生活带来很多便利。在互联网的普及,云计算、大数据、手机APP等新技术的促进下,物联网系统的架构体系逐渐朝着平台化方向发展。同时物联网具有多学科综合性,其涉及的技术多种多样,导致涉及的标准也非常多,物联网产业面临着行业标准尚未统一的问题。[1]不同类型、不同厂商甚至不同应用场景的物联网终端的组网方式和接入协议都可能存在差异。为了适应这一变化和规范物联网产业,国内外各大互联网企业纷纷推出自己的物联网平台,例如Google的Android Things、亚马逊的AWS IoT、百度的天工、阿里巴巴集团的阿里云物联网套件、腾讯的物联网通信服务等。这些物联网平台都希望通过建立物联网终端的接入标准,实现设备数据采集上传云端并在云平台上集成物联网各种应用场景的解决方案,从而构建物联网的生态链。
众多平台的出现的确给物联系统的运营带来便利,然而对于产品研发初期的中小型物联网企业,研发的效率直接影响市场竞争力。[2]当遇到缺乏硬件产业链支持和研发团队尚未成熟的情况时,物联网硬件产品的研发重点往往优先考虑产品的创新多样,导致产品无法主动适应各大物联网平台的接入规范;当企业需要根据市场发展方向反复调整产品的功能需求时,传统的物联网平台往往不能做到及时适应产品研发和运营的变化。因此,有必要设计和实现一种适用于多种接入方式的高扩展性物联网服务器架构,保障各种类型的终端快速接入系统,以满足物联网产品研发对物联网平台的需求。
传统的物联网利用各种低功耗广域网络(Low Power Wide Area Network,简称LPWAN)进行数据传输,上位机依照传输协议接收和处理下位机传送的数据,并对下位机发出控制指令。在互联网环境下的物联网系统中,上位机是设备终端信息传递的关键模块,主要负责接收终端设备的网络数据进行业务逻辑处理,对数据进行加工后存储到数据存储系统,并接受管理后台的控制。在当前互联网应用场景下上位机需要承载大量终端设备,系统将面临着高并发连接和海量数据处理的压力。因此需要对物联网系统功能模块进行解耦,设计合理的服务器架构,利用服务器集群资源分解压力才能保障系统的正常运行。
传统物联网服务器架构如图1所示。其中DNS域名解析负责对网关服务器集群进行负载均衡;网关服务器(Gateway Server)主要负责分流终端设备的网络连接,对网络数据进行收发、拆包、加解密、校验和过滤等逻辑处理后传递给中心服务器(Center Server);中心服务器负责将数据按业务逻辑处理后把需要存储的数据传输到数据库服务器(DB Server)中,并从数据库中读取后台控制指令后通过网关服务器下发到终端设备;数据库服务器主要负责将数据写入数据库(Database)中。系统后台网站负责终端设备数据的展示和管理,并向手机APP等应用提供服务接口。手机APP负责向用户展示数据和操控终端设备。
整个架构按从功能模块上主要分为4个模块:
(1)网络模块,负责面向终端设备的网络连接。模块通过在DNS域名管理中配置多个网关服务器的A记录,利用DNS基于地理位置的域名解析完成网关服务器负载均衡。通过网关服务器集群分流了终端设备,从而提高了系统对终端设备在线数量的承载力。
(2)业务逻辑模块,架构的核心模块。中心服务器对接收到的设备数据加工后通过数据模块进行存储,并按业务逻辑通过网络模块向终端设备发送指令。
(3)数据模块,负责对数据进行存储。通过数据库服务器利用读写分离、间接批量写入等技术方式把数据写入数据库中,缓解架构面对海量数据存储的压力。
(4)后台管理模块,负责系统的业务管理功能。后台网站主要面向管理员提供终端设备的管理,手机APP主要面向用户提供终端设备的管理。
该架构有效地解决了互联网环境下大量终端设备带来的系统压力,但在实际应用中还存在以下问题:
(1)系统功能扩展性不足,架构面对功能需要扩展或改变时弹性不足。当前物联网系统朝着支持多种应用场景、多种类型设备接入的综合性系统的方向发展,当有新的终端设备接入或系统需要加入其他平台联合运营时,网关服务器和中心服务器不可避免地需要调整功能,架构需要迭代才能满足新的业务需求,缺乏高可用性。
(2)系统承载能力不足,架构里终端设备的数据包经过网关服务器接收和校验后直接传递给中心服务器进行业务逻辑处理,适合面对流量相对平稳的业务。但当每秒事务处理数(Transactions Per Second,简称TPS)发生激增时,架构缺乏削峰填谷的手段,容易造成数据因处理不及时而发生挤压,导致整个系统瘫痪。
(3)缺乏服务器之间通讯的手段。后台网站和中心服务器由于使用不同的编程技术和隶属于不同模块,它们之间没有直接的数据连接,当业务模块有指令需要下达给终端设备时,往往使用数据库作为中转。如表1所示,后台网站将需要发送的指令数据存入数据库的指令下发表中,中心服务器需要反复地查询表中数据,并在设备在线时把指令下发。该方式效率低且不优雅,难以胜任复杂的业务流程,例如第三方平台身份验证、充值、计费等功能。
表1 指令下发表
因此,需要对该服务器框架做进一步的改进以满足系统需求。考虑到中小企业研发力量有限的问题,架构在技术上尽量考虑使用成熟的第三方组件,同时根据物联网应用场景的特点和系统运营的需求对架构做进一步解耦,使框架具备高扩展性和高伸缩性,以便能快速完成新终端设备和新平台的接入等扩展功能。
消息列队是分布式系统中重要的组件,众多成功案例证明消息列队能优化系统架构和提高系统抗压性能,[3-4]起到降低架构的耦合性及削峰填谷的作用。成熟的消息列队例如Kafka、RabbitMQ、ZeroMQ等,各有特点及适合运用场景。从中小型物联网企业对系统架构伸缩性的需求上分析,要求具备以下的特点:
(1)系统研发期架构的部署尽可能简单。架构中的所有模块能同时运行在同一台服务器设备上,以降低研发所需硬件资源,程序应方便安装、运行、升级和演示。
(2)系统运营期可根据生产情况进行调整架构部署。在系统运营初期系统压力较小的情况下,架构可以减少部署所需服务器设备甚至多个系统同时部署在一台服务器上,以便节约资源,降低运营成本和减少维护工作量;当系统压力较大时可根据情况增加服务器设备及网络资源,以集群部署实现高可用性和吞吐量,提高系统的承载力。
(3)系统支持多种程序编码语言。从敏捷开发的角度上开发主要以人为核心,系统是迭代和循序渐进的开发方法。[5-6]架构在研发初期常会遇到编码语言和运行平台不统一,需要取舍以优先保证研发速度的情况。
考虑到系统要求满足支持多编解码和跨语言跨平台、支持多种连接方式、各组件相互独立和组件热插拔的条件,选用ZeroMQ作为架构的消息列队。
ZeroMQ支持在同一进程中的不同线程之间(inproc)、本地进程之间(ipc)、远程进程之间(TCP)等数据传输方式,支持Request-Reply、Publish-Subscribe、Parallel Pipeline等模式,支持Router-Dealer、Router-Req、Router-Rep等消息转发方式(Broker),以及使用多段消息的信封机制(Message Envelopes)。[7]通过这些特性可以改进架构里请求-响应(Request Client-Reply Server)模型,并利用ROUTER对架构中的网关服务器和中心服务器的全互联连接模式进行简化。在实际运用中,为了方便管理网络中的服务器和数据的走向,需要人工对服务器设置唯一的标识。如下代码所示,初始化ZeroMQ对象成功后,利用zmq_setsockopt接口设置ZMQ_IDENTITY属性绑定服务器标识。当Broker收到ZMQ传递的数据时,通过标识可以判断数据来源及控制数据走向。
设置ZMQ对象标识代码:
//以DEALER模式初始化ZMQ对象
auto server=zmq_socket(_context,ZMQ_DEALER);
if(server==nullptr)
{
return nullptr;
}
//设置zmq对象标识
if(zmq_setsockopt(server,ZMQ_IDENTITY,&_id,sizeof(uint8_t))!=0)
{
return nullptr;
}
对架构的所有服务器进行标识管理后,通过ROUTER模式可以设计Broker作为所有数据的转发层。如图2所示,架构中所有服务器都通过DEALER模式连接上消息转发服务器(Broker Server),1号服务器并不直接连接10号服务器。当1号服务器收到网络数据后,需要把数据传递给10号服务器进行业务处理时,数据是先通过Router-Dealer的连接投递给消息转发服务器,通过消息列队的负载均衡处理后,再发送到10号服务器上。
架构中消息转发服务器起到中间层的作用,所有数据传递都通过其进行中转。对于Socket服务器内部,无论是IOCP还是EPOLL模型,都需要使用I/O线程池处理Socket事件。如果多线程环境使用同一个ZeroMQ对象与Broker交换数据,将不可避免地需要对其加锁防止资源竞争,从而影响处理Socket事件的效率。为了避免产生额外的开销,在每个I/O线程创建后根据线程ID关联一个ZeroMQ对象,以inproc连接方式把数据发送到消息线程。在消息线程中采用zmq_poll处理连接信号,把I/O线程数据再统一发送给Broker。如图3所示,由于每个I/O线程都使用专用的ZeroMQ对象,无需再使用加锁影响数据的收发,实现无锁消息发送模型。
通过消息列队的设计,架构中所有模块都直接通过消息转发服务器转发数据,解耦了架构中的网络连接,连接数从M×N简化为M+N,降低了架构的网络复杂度。同时由于ZeroMQ的连接和收发的透明性程度高,提高了架构的横向扩展性。在系统抗压性方面,数据在消息转发服务器通过消息列队和负载均衡处理,起到了削峰填谷的作用。虽然数据中转产生了系统性能上额外的开销,但各个模块与消息转发服务器的连接处于内网环境下,数据因中转投递带来的延时对于物联网系统可以忽略。
通过消息列队优化了架构中的数据传递,使得系统可以通过分布式的方式灵活实现业务逻辑的拆分。当对复杂的业务逻辑通过拆分解耦时,架构中拆分出来的多个服务器会产生对访问同一组数据的需求。常规数据共享的解决方案中,无论是通过服务器之间的数据交换还是通过数据库中转,都影响系统的运行效率和提高研发的复杂度。而内存数据库的出现,提供了一种解决分布式架构下数据共享的有效方法。[8]在众多内存数据库产品中,Redis作为开源的高性能键值对(key-value)内存数据库,可以在系统中可以起到作数据库、缓存和消息中间件的作用。通过Redis对架构中的存储模块进行改进,可以降低数据库的查询量和提高数据访问速度。[9]
架构引入Redis后系统逻辑的关键数据应尽可能加载到Redis后再对其进行操作。当服务器需要操作数据时,先请求Redis判断数据是否存在,如果不存在就先从数据库中把数据读取出来并初始化到Redis中,数据根据业务逻辑运算过后,需要对Redis的数据进行更新,同时更新数据库,如图4所示。
由于服务器的业务数据不再存储在进程内存里,虽然增加了研发的工作量和代码复杂度,但新增的Redis模块给整个架构带来了以下优势:
(1)提供便捷的数据共享方式。当系统需要接入其他平台运营时,可以在不改变系统原有服务器的情况下,通过增加一个平台业务逻辑服务器,通过Redis轻松完成数据的共享。同时数据共享也为复杂的跨服务器业务流程开发提供了方便。
(2)引入数据容灾机制。一般服务器上数据存储在服务器进程的内存中,当服务器程序崩溃时业务数据有可能丢失。此时数据存储在Redis中,服务器发生崩溃并不会影响到数据,只需要重启服务器即可恢复生产状态。同时Redis自带数据永久化功能,保证了架构的健壮性。[10]
针对物联网复合型平台系统的特点以及当前中小企业研发的需求,通过ZeroMQ、Redis等技术对原有架构进行改造,为架构提供数据列队、数据交换、数据共享等服务,使架构具有高扩展性。消息转发服务器作为架构的核心以星形拓扑为其他服务器提供数据交换服务,并通过标识对其他服务器进行管理,如图5所示。架构把不同终端设备的服务器进行分组,根据终端设备的特点来规划服务器组的功能需求。如设备1服务器组作为传统的网关服务器加中心服务器的组合;设备2服务器组作为兼容消息队列遥测传输(MQTT)协议,并为第三方物联网平台提供交互数据的组合。不同服务器组之间相互独立,架构可以根据业务需求添加新的服务器组,以丰富系统功能,实现复合型物联网平台。
架构中的服务器与消息转发服务器都使用相同的ZeroMQ连接模型,减轻了开发工作量,使开发团队可以把精力集中在业务逻辑上。消息转发服务器作为系统的核心只负责维护数据列队和数据交换,不涉及复杂业务逻辑,避免因崩溃引发整个系统的瘫痪。Redis内存服务器提供了便捷的数据共享及容灾机制,保证了架构的健壮性。经过优化的架构具有高扩展性,可快速接入新的功能模块,如根据业务和运维需求添加第三方支付功能、日志管理和服务监控功能等模块,以保障当前物联网系统整个生命周期的功能需求。
为了保证测试环境的广泛性,本文采用常见的云服务器ECS(Elastic Compute Service)作为测试服务器,在不改变操作系统默认配置的情况下仅对程序使用-O3优化的情况下测试架构的测试环境。测试模拟物联网系统典型的事务流程,以下位机通过TCP协议连接平台后发送64 Byte字节的上报数据,服务器进行数据解析并模拟数据写入数据库后返回16 Byte字节的数据为一完整事务流程,对架构进行ping-pong测试。
为了测试架构的伸缩性,测试分成两个方向进行,分别测试架构的横向扩展性和纵向扩展性。在横向扩展性方面,把测试服务器分成单机模式和群组模式进行对比测试。两组测试模式的服务器配置如表2所示,服务器实例的CPU为Intel Xeon(Cascade Lake)Platinum 8269,其中单机模式把架构中所有模块都部署在同一台服务器上运行;群组模式采用服务器群组架构,并按模块的运行特点对硬件配置进行了调整。
表2 测试服务器配置表
在纵向扩展性方面,通过调整架构服务器端线程的数量来测试在不同线程数目下架构的性能。服务器端的I/O线程和Worker线程开启数量分别为2线程、4线程、CPU个数+2线程数。两种测试方向的测试结果如图6~图7所示,架构在多线程和群组模式下的性能良好,群组模式和提升线程数都能提升架构的TPS。而由于组群模式下数据包需要在不同服务器实例之间传递,导致事务的响应时间(Response Time,简称RT)要大于单机模式,但通过调整线程数量的方式,提高系统的事务处理速度来缓解其带来的影响。
测试结果表明,架构的配置非常灵活。架构在单机模式下可用于研发、测试和演示环境,为企业降低研发成本。在群组模式下,架构表现出了良好的事务吞吐量,可用于生产环境并有充足的扩展空间。整个架构只需要更改部署方式就能快速切换工作场景,显示了良好的扩展性,适用于物联网平台的搭建。
本文针对当前复合型物联网平台功能需求的特点,基于ZeroMQ和Redis技术对传统物联网服务器架构进行解耦,设计和实现了一种高扩展性物联网服务器架构。使物联网系统具有分布式系统的横向扩展性,满足中小型物联网企业对产品研发和运营的要求,为灵活地接入多种物联网终端设备及与第三方平台联运提供保障。该架构已接入智能路灯、智能充电桩、智能安检门等多种终端设备,并与第三方智慧城市管理系统和充电平台进行了数据对接,整个系统在生产环境中运行状态良好,达到了设计目标。