陳強 武佳佳



摘要 隨著更多的物聯網設備接入,給提供高并發物聯網服務器帶來了挑戰。基于此本文首先研究目前常用方法找出不足。然后,提出使用JavaNIO庫Netty解決高并發問題。以可配置方式解決物聯網數據傳輸過程的拆包及粘包問題。并提出三種級別數據通道,以滿足物聯網數據傳輸的不同需求。最后,簡要分析物聯網應用服務器及用戶終端展現方式。提出目前系統不足及今后的工作重點。
【關鍵詞】物聯網服務器 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,
}
if (in.readableBytes()<=headerSize){
//headerSize是表1中的頭信息長度
returnnull;
}
in.markReaderlndex0∥記錄數據讀到當時位置
intrequestld= in.readlnt();
intnodeld= in.readlnt();
bytetype = in.readByte();
intframeld= in.readlnt();
shortlengrh= in.readShort();
if (in.readableBytes()
//如果數據緩存沒有達到消息頭中指定的消息體長度等待消息傳送足夠
in.resetReaderlndex();//回到上一次數據讀取位置
returnnull,
}
經過解碼器后保證每次返回的是一個完整的定義的數據對象。
(1)獲取數據后按系統設計進行實時轉發給其他連接于服務器的客戶端
chx=SocketOnLineRegisterDevice.get(detID);
if (chx!= null&&chx.isActive(》{
chx.writeAndFlush(resp);)
(2)將數據存于內存數據庫或硬盤數據庫服務器中,物聯網應用服務器可通過HTTP協調獲取準實時或非實時數據。內存數據庫本系統使用redis內存數據庫平臺。通過鍵值對的方式保存數據。持久化數據庫平臺支持Mysql及Oracle數據庫。
對于第一種數據類型實時性控制高,常用于用戶終端對物聯網終端模塊的控制,如:開關、終端設備實時控制等。此類數據不存儲,只進行轉發。第二種類型的數據存儲于內存數據庫,物聯網應用服務器可讀取內存數據庫內容,也可依據需求進行持久化存儲。第三種類型數據存儲時間相對較長對需要持久化的數據進行保存。
微信及Web頁面端是無法直接使用Socekt編程,在HTML5中提供了WebSocket方式,本系統并發物聯網服務器開發支持WebSocket客戶端支持數據收發。
4 結語
本文設計了基于Netty的并發物聯網服務器,為物聯網終端提供了可靠的服務保障。目前服務器己應用于多個物聯網項目中,包括電力設備數據采集及農業智能項目數據采集。應用過程中發現數據安全性是未來研究與改進的方面,在物聯網數據采集過程中保證數據有效、安全提出更高的要求。相信在發展過程中給物聯網發展起到重要作用。
參考文獻
[1]龔鵬,曾興斌.基于Net ty框架的數據通訊服務系統的設計[J],無線通信技術,2016, 25; No. 97 (01): 49-52.
[2]梁明剛.Linux下基于epoll_線程池高并發服務器實現研究[J].武漢工業學院學報,2012 (03):54-59.
[3]姜景根,李祥,基于Java的多線程并發服務器的設計與應用[J].電腦與信息技術,2007:15-17,42.
[4]汪悅,管弋銘,李夢蓉等.基于物聯網的智慧家庭健康醫療系統[J].光通信研究,2018,02 (205):1-5.
[5]謝佳佳.基于物聯網的智能植物工廠電子商務系統設計[J],天津職業技術師范大學學報,2015 (04): 26-29.
[6]韓星,基于Netty的RPC通信系統的編解碼技術研究[J].電腦知識與技術,2017 (26):104-107