基于Netty高并发物联网服务器研究与设计

随着更多的物联网设备接入,给提供高并发物联网服务器带来了挑战。基于此本文首先研究目前常用方法找出不足。然后,提出使用JavaNIO库Netty解决高并发问题。以可配置方式解决物联网数据传输过程的拆包及粘包问题。并提出三种级别数据通道,以满足物联网数据传输的不同需求。最后,简要分析物联网应用服务器及用户终端展现方式。提出目前系统不足及今后的工作重点。

1 引言

随着物联网技术的快速发展,传统设备加入了传感器及网络能力,这使得它们能够实时感知环境信息,如:智能家居或家庭、智能城市、环境监测、智能医疗、食品溯源、国防军事、智能交通和智能环境等,客户端的规模正在快速增长,在某一时刻向服务器并发地发送数据请求的客户端随之增加,如何在短时间内提高服务器并发处理能力是数据通信服务系统开发面临的一个重要问题。针对数据通信特性要求,文献[2]提出使用Linux下基于epoll+线程池高并发服务器方式,此种方式对系统依赖过高。文献[3]提出使用Java基础Socket套接字编程+socket,此方式解决了对操作系统依赖问题,但对于高并发传输时生成过多线程,使服务器性能下降。文献[4]使用服务器应用软件、网关模块和各种医疗终端,医疗终端采用WIFI、蓝牙或者Lora将数据传输到网关模块。此方式问题一是如果网关模块出现故障,所有的采集模块将处于瘫痪状态。二是每一个采集模块对于服务器来说无法直接了解模块状态,较难管理。文献[5]中提出使用Tomcat+JSP+servlet+MVC的Web服务方式,此方法对于终端设备有嵌入式操作系统有HTTP协议栈,但大多数终端低成本要求无法使用嵌入式操作系统。目前较常用的网络模块使用TCP方式传输数据,此方法无法满足需求。本文提出使用基于Netty实现JavaNIO方式开发高并发物联网服务器,物联网前端采集使用GPRS、3 G/5G及NB-IOT数据通信方式。提供了一整套前端数据采集与后端数据整理、采集及展示设计方案。

2 系统架构

系统由物联网终端、物联网并发服务器、物联网业务服务器、数据存储服务器、物联网应用服务器以及用户展示控制端(智能手机、微信、网页端)如图1。物联网终端模块数据主要为两类:一是定时从物联网采集数据,此数据通常由物联网终端发起。二是从用户或其它控制模块发送给物联网终端,此方式也是目前物联网实现相对困难的技术。物联网业务服务器主要解决,物联网并发服务器接收数据后续处理,防止数据进入并发服务器后因数据存储时间长而影响系统整体性能,数据分发到多台业务服务器中进行数据库操作。数据存储服务器分为硬件数据与内存数据库,硬盘数据库主要存储持久化的数据,内存数据库存储实时性要求高但不持久化存储的数据。物联网应用服务器为用户提供智能手机、微信小程序及网页端展示数据与控制。本系统数据通道级别分为三级:第一级数据直接通过物联网并发服务器转发两端(用户终端、物联网终端)的实时数据。第二级是两端通过内存型数据库进行转发的准实时数据。第三级是两端的数据通过硬盘数据保存与转发。

3 系统设计

2007年JDKl.7发布,升级后的NI02.0提供了异步文件通道和异步套接字通道的实现,文件处理能力有了进一步的提升。尽管NIO的吞吐量和可靠性相对于传统的BIO(同步阻塞式IO)有了质的飞跃,但其类库和API十分繁杂,使用起来非常困难。再加上粘包拆包、断线重连等可靠性处理的工作量和复杂度都非常大,因此直接使用NIO开发复杂度增大,使用开发周期及成本上升,给后期物联网服务器升级维护带来困难。为了简化NIO网络编程,一些开源项目发布供用户使用、学习、修改。其中Netty、Mina是两个常用框架。其中Mina由于目前不再持续更新,使用风险升高。Netty的功能、性能、健壮性、可定制和可扩展性已经得到了大量商业项目的成功验证。包括阿里巴巴等知名公司使用Netty进行业务开发及扩展。本文基于Netty框架,开发并发高性能物联网服务器,使通信系统的性能和可靠性均得到了极大的提高。

TCP粘包拆包问题无法在传输层处理,需要通过用户自定义方式进行处理。依据网络传输数据特性常常使用的解决方法有三种:一是消息保持固定长度;二是在每一帧消息的尾部使用特殊字符如$$等类型的字符串;三是将消息分为消息头和消息体,在消息头中存储包括消息长度字段。文献[6]比较三种方式的特点,由于受到物联网终端成本、技术开发能力限制,有可能采用不同方式。本系统考虑适配性能,设计采用可配置的方式支持三种方式。

public fin alstaticbooleanU SE_FIXEDLENGTH= false;//消息定长

publicfinalsraricbooleanUSE_DELIMITER= true,//特殊分割符

public finalstaticbooleanUSE_LENGTHFIELD= false;//消息头与消息体

以上三者是互斥,只能使用一种。每一种类型对应一种解码器,特殊分割符及消息头类型要继承LengthFieldBasedFrameDecoder和DelimiterBasedFrameDecoder并重写Decode方法。

并发服务器类图如图2。

以LengthFieldBasedFrameDecoder的子类为例:协议头设计如表l。

代码如下:

@Override

protected Object decode(ChannelHandlerContextctx, ByteBufin) throws Exception{

if (in==null){

returnnull,

0

发表评论

邮箱地址不会被公开。