陳強(qiáng) 武佳佳
摘要 隨著更多的物聯(lián)網(wǎng)設(shè)備接入,給提供高并發(fā)物聯(lián)網(wǎng)服務(wù)器帶來(lái)了挑戰(zhàn)?;诖吮疚氖紫妊芯磕壳俺S梅椒ㄕ页霾蛔恪H缓?,提出使用JavaNIO庫(kù)Netty解決高并發(fā)問(wèn)題。以可配置方式解決物聯(lián)網(wǎng)數(shù)據(jù)傳輸過(guò)程的拆包及粘包問(wèn)題。并提出三種級(jí)別數(shù)據(jù)通道,以滿足物聯(lián)網(wǎng)數(shù)據(jù)傳輸?shù)牟煌枨?。最后,?jiǎn)要分析物聯(lián)網(wǎng)應(yīng)用服務(wù)器及用戶終端展現(xiàn)方式。提出目前系統(tǒng)不足及今后的工作重點(diǎn)。
【關(guān)鍵詞】物聯(lián)網(wǎng)服務(wù)器 Netty 拆包 粘包數(shù)據(jù)通道
1 引言
隨著物聯(lián)網(wǎng)技術(shù)的快速發(fā)展,傳統(tǒng)設(shè)備加入了傳感器及網(wǎng)絡(luò)能力,這使得它們能夠?qū)崟r(shí)感知環(huán)境信息,如:智能家居或家庭、智能城市、環(huán)境監(jiān)測(cè)、智能醫(yī)療、食品溯源、國(guó)防軍事、智能交通和智能環(huán)境等,客戶端的規(guī)模正在快速增長(zhǎng),在某一時(shí)刻向服務(wù)器并發(fā)地發(fā)送數(shù)據(jù)請(qǐng)求的客戶端隨之增加,如何在短時(shí)間內(nèi)提高服務(wù)器并發(fā)處理能力是數(shù)據(jù)通信服務(wù)系統(tǒng)開(kāi)發(fā)面臨的一個(gè)重要問(wèn)題。針對(duì)數(shù)據(jù)通信特性要求,文獻(xiàn)[2]提出使用Linux下基于epoll+線程池高并發(fā)服務(wù)器方式,此種方式對(duì)系統(tǒng)依賴過(guò)高。文獻(xiàn)[3]提出使用Java基礎(chǔ)Socket套接字編程+socket,此方式解決了對(duì)操作系統(tǒng)依賴問(wèn)題,但對(duì)于高并發(fā)傳輸時(shí)生成過(guò)多線程,使服務(wù)器性能下降。文獻(xiàn)[4]使用服務(wù)器應(yīng)用軟件、網(wǎng)關(guān)模塊和各種醫(yī)療終端,醫(yī)療終端采用WIFI、藍(lán)牙或者Lora將數(shù)據(jù)傳輸?shù)骄W(wǎng)關(guān)模塊。此方式問(wèn)題一是如果網(wǎng)關(guān)模塊出現(xiàn)故障,所有的采集模塊將處于癱瘓狀態(tài)。二是每一個(gè)采集模塊對(duì)于服務(wù)器來(lái)說(shuō)無(wú)法直接了解模塊狀態(tài),較難管理。文獻(xiàn)[5]中提出使用Tomcat+JSP+servlet+MVC的Web服務(wù)方式,此方法對(duì)于終端設(shè)備有嵌入式操作系統(tǒng)有HTTP協(xié)議棧,但大多數(shù)終端低成本要求無(wú)法使用嵌入式操作系統(tǒng)。目前較常用的網(wǎng)絡(luò)模塊使用TCP方式傳輸數(shù)據(jù),此方法無(wú)法滿足需求。本文提出使用基于Netty實(shí)現(xiàn)JavaNIO方式開(kāi)發(fā)高并發(fā)物聯(lián)網(wǎng)服務(wù)器,物聯(lián)網(wǎng)前端采集使用GPRS、3 G/5G及NB-IOT數(shù)據(jù)通信方式。提供了一整套前端數(shù)據(jù)采集與后端數(shù)據(jù)整理、采集及展示設(shè)計(jì)方案。
2 系統(tǒng)架構(gòu)
系統(tǒng)由物聯(lián)網(wǎng)終端、物聯(lián)網(wǎng)并發(fā)服務(wù)器、物聯(lián)網(wǎng)業(yè)務(wù)服務(wù)器、數(shù)據(jù)存儲(chǔ)服務(wù)器、物聯(lián)網(wǎng)應(yīng)用服務(wù)器以及用戶展示控制端(智能手機(jī)、微信、網(wǎng)頁(yè)端)如圖1。物聯(lián)網(wǎng)終端模塊數(shù)據(jù)主要為兩類:一是定時(shí)從物聯(lián)網(wǎng)采集數(shù)據(jù),此數(shù)據(jù)通常由物聯(lián)網(wǎng)終端發(fā)起。二是從用戶或其它控制模塊發(fā)送給物聯(lián)網(wǎng)終端,此方式也是目前物聯(lián)網(wǎng)實(shí)現(xiàn)相對(duì)困難的技術(shù)。物聯(lián)網(wǎng)業(yè)務(wù)服務(wù)器主要解決,物聯(lián)網(wǎng)并發(fā)服務(wù)器接收數(shù)據(jù)后續(xù)處理,防止數(shù)據(jù)進(jìn)入并發(fā)服務(wù)器后因數(shù)據(jù)存儲(chǔ)時(shí)間長(zhǎng)而影響系統(tǒng)整體性能,數(shù)據(jù)分發(fā)到多臺(tái)業(yè)務(wù)服務(wù)器中進(jìn)行數(shù)據(jù)庫(kù)操作。數(shù)據(jù)存儲(chǔ)服務(wù)器分為硬件數(shù)據(jù)與內(nèi)存數(shù)據(jù)庫(kù),硬盤(pán)數(shù)據(jù)庫(kù)主要存儲(chǔ)持久化的數(shù)據(jù),內(nèi)存數(shù)據(jù)庫(kù)存儲(chǔ)實(shí)時(shí)性要求高但不持久化存儲(chǔ)的數(shù)據(jù)。物聯(lián)網(wǎng)應(yīng)用服務(wù)器為用戶提供智能手機(jī)、微信小程序及網(wǎng)頁(yè)端展示數(shù)據(jù)與控制。本系統(tǒng)數(shù)據(jù)通道級(jí)別分為三級(jí):第一級(jí)數(shù)據(jù)直接通過(guò)物聯(lián)網(wǎng)并發(fā)服務(wù)器轉(zhuǎn)發(fā)兩端(用戶終端、物聯(lián)網(wǎng)終端)的實(shí)時(shí)數(shù)據(jù)。第二級(jí)是兩端通過(guò)內(nèi)存型數(shù)據(jù)庫(kù)進(jìn)行轉(zhuǎn)發(fā)的準(zhǔn)實(shí)時(shí)數(shù)據(jù)。第三級(jí)是兩端的數(shù)據(jù)通過(guò)硬盤(pán)數(shù)據(jù)保存與轉(zhuǎn)發(fā)。
3 系統(tǒng)設(shè)計(jì)
2007年JDKl.7發(fā)布,升級(jí)后的NI02.0提供了異步文件通道和異步套接字通道的實(shí)現(xiàn),文件處理能力有了進(jìn)一步的提升。盡管NIO的吞吐量和可靠性相對(duì)于傳統(tǒng)的BIO(同步阻塞式IO)有了質(zhì)的飛躍,但其類庫(kù)和API十分繁雜,使用起來(lái)非常困難。再加上粘包拆包、斷線重連等可靠性處理的工作量和復(fù)雜度都非常大,因此直接使用NIO開(kāi)發(fā)復(fù)雜度增大,使用開(kāi)發(fā)周期及成本上升,給后期物聯(lián)網(wǎng)服務(wù)器升級(jí)維護(hù)帶來(lái)困難。為了簡(jiǎn)化NIO網(wǎng)絡(luò)編程,一些開(kāi)源項(xiàng)目發(fā)布供用戶使用、學(xué)習(xí)、修改。其中Netty、Mina是兩個(gè)常用框架。其中Mina由于目前不再持續(xù)更新,使用風(fēng)險(xiǎn)升高。Netty的功能、性能、健壯性、可定制和可擴(kuò)展性已經(jīng)得到了大量商業(yè)項(xiàng)目的成功驗(yàn)證。包括阿里巴巴等知名公司使用Netty進(jìn)行業(yè)務(wù)開(kāi)發(fā)及擴(kuò)展。本文基于Netty框架,開(kāi)發(fā)并發(fā)高性能物聯(lián)網(wǎng)服務(wù)器,使通信系統(tǒng)的性能和可靠性均得到了極大的提高。
TCP粘包拆包問(wèn)題無(wú)法在傳輸層處理,需要通過(guò)用戶自定義方式進(jìn)行處理。依據(jù)網(wǎng)絡(luò)傳輸數(shù)據(jù)特性常常使用的解決方法有三種:一是消息保持固定長(zhǎng)度;二是在每一幀消息的尾部使用特殊字符如$$等類型的字符串;三是將消息分為消息頭和消息體,在消息頭中存儲(chǔ)包括消息長(zhǎng)度字段。文獻(xiàn)[6]比較三種方式的特點(diǎn),由于受到物聯(lián)網(wǎng)終端成本、技術(shù)開(kāi)發(fā)能力限制,有可能采用不同方式。本系統(tǒng)考慮適配性能,設(shè)計(jì)采用可配置的方式支持三種方式。
public fin alstaticbooleanU SE_FIXEDLENGTH= false;//消息定長(zhǎng)
publicfinalsraricbooleanUSE_DELIMITER= true,//特殊分割符
public finalstaticbooleanUSE_LENGTHFIELD= false;//消息頭與消息體
以上三者是互斥,只能使用一種。每一種類型對(duì)應(yīng)一種解碼器,特殊分割符及消息頭類型要繼承LengthFieldBasedFrameDecoder和DelimiterBasedFrameDecoder并重寫(xiě)Decode方法。
并發(fā)服務(wù)器類圖如圖2。
以LengthFieldBasedFrameDecoder的子類為例:協(xié)議頭設(shè)計(jì)如表l。
代碼如下:
@Override
protected Object decode(ChannelHandlerContextctx, ByteBufin) throws Exception{
if (in==null){
returnnull,
}
if (in.readableBytes()<=headerSize){
//headerSize是表1中的頭信息長(zhǎng)度
returnnull;
}
in.markReaderlndex0∥記錄數(shù)據(jù)讀到當(dāng)時(shí)位置
intrequestld= in.readlnt();
intnodeld= in.readlnt();
bytetype = in.readByte();
intframeld= in.readlnt();
shortlengrh= in.readShort();
if (in.readableBytes()
//如果數(shù)據(jù)緩存沒(méi)有達(dá)到消息頭中指定的消息體長(zhǎng)度等待消息傳送足夠
in.resetReaderlndex();//回到上一次數(shù)據(jù)讀取位置
returnnull,
}
經(jīng)過(guò)解碼器后保證每次返回的是一個(gè)完整的定義的數(shù)據(jù)對(duì)象。
(1)獲取數(shù)據(jù)后按系統(tǒng)設(shè)計(jì)進(jìn)行實(shí)時(shí)轉(zhuǎn)發(fā)給其他連接于服務(wù)器的客戶端
chx=SocketOnLineRegisterDevice.get(detID);
if (chx!= null&&chx.isActive(》{
chx.writeAndFlush(resp);)
(2)將數(shù)據(jù)存于內(nèi)存數(shù)據(jù)庫(kù)或硬盤(pán)數(shù)據(jù)庫(kù)服務(wù)器中,物聯(lián)網(wǎng)應(yīng)用服務(wù)器可通過(guò)HTTP協(xié)調(diào)獲取準(zhǔn)實(shí)時(shí)或非實(shí)時(shí)數(shù)據(jù)。內(nèi)存數(shù)據(jù)庫(kù)本系統(tǒng)使用redis內(nèi)存數(shù)據(jù)庫(kù)平臺(tái)。通過(guò)鍵值對(duì)的方式保存數(shù)據(jù)。持久化數(shù)據(jù)庫(kù)平臺(tái)支持Mysql及Oracle數(shù)據(jù)庫(kù)。
對(duì)于第一種數(shù)據(jù)類型實(shí)時(shí)性控制高,常用于用戶終端對(duì)物聯(lián)網(wǎng)終端模塊的控制,如:開(kāi)關(guān)、終端設(shè)備實(shí)時(shí)控制等。此類數(shù)據(jù)不存儲(chǔ),只進(jìn)行轉(zhuǎn)發(fā)。第二種類型的數(shù)據(jù)存儲(chǔ)于內(nèi)存數(shù)據(jù)庫(kù),物聯(lián)網(wǎng)應(yīng)用服務(wù)器可讀取內(nèi)存數(shù)據(jù)庫(kù)內(nèi)容,也可依據(jù)需求進(jìn)行持久化存儲(chǔ)。第三種類型數(shù)據(jù)存儲(chǔ)時(shí)間相對(duì)較長(zhǎng)對(duì)需要持久化的數(shù)據(jù)進(jìn)行保存。
微信及Web頁(yè)面端是無(wú)法直接使用Socekt編程,在HTML5中提供了WebSocket方式,本系統(tǒng)并發(fā)物聯(lián)網(wǎng)服務(wù)器開(kāi)發(fā)支持WebSocket客戶端支持?jǐn)?shù)據(jù)收發(fā)。
4 結(jié)語(yǔ)
本文設(shè)計(jì)了基于Netty的并發(fā)物聯(lián)網(wǎng)服務(wù)器,為物聯(lián)網(wǎng)終端提供了可靠的服務(wù)保障。目前服務(wù)器己應(yīng)用于多個(gè)物聯(lián)網(wǎng)項(xiàng)目中,包括電力設(shè)備數(shù)據(jù)采集及農(nóng)業(yè)智能項(xiàng)目數(shù)據(jù)采集。應(yīng)用過(guò)程中發(fā)現(xiàn)數(shù)據(jù)安全性是未來(lái)研究與改進(jìn)的方面,在物聯(lián)網(wǎng)數(shù)據(jù)采集過(guò)程中保證數(shù)據(jù)有效、安全提出更高的要求。相信在發(fā)展過(guò)程中給物聯(lián)網(wǎng)發(fā)展起到重要作用。
參考文獻(xiàn)
[1]龔鵬,曾興斌.基于Net ty框架的數(shù)據(jù)通訊服務(wù)系統(tǒng)的設(shè)計(jì)[J],無(wú)線通信技術(shù),2016, 25; No. 97 (01): 49-52.
[2]梁明剛.Linux下基于epoll_線程池高并發(fā)服務(wù)器實(shí)現(xiàn)研究[J].武漢工業(yè)學(xué)院學(xué)報(bào),2012 (03):54-59.
[3]姜景根,李祥,基于Java的多線程并發(fā)服務(wù)器的設(shè)計(jì)與應(yīng)用[J].電腦與信息技術(shù),2007:15-17,42.
[4]汪悅,管弋銘,李夢(mèng)蓉等.基于物聯(lián)網(wǎng)的智慧家庭健康醫(yī)療系統(tǒng)[J].光通信研究,2018,02 (205):1-5.
[5]謝佳佳.基于物聯(lián)網(wǎng)的智能植物工廠電子商務(wù)系統(tǒng)設(shè)計(jì)[J],天津職業(yè)技術(shù)師范大學(xué)學(xué)報(bào),2015 (04): 26-29.
[6]韓星,基于Netty的RPC通信系統(tǒng)的編解碼技術(shù)研究[J].電腦知識(shí)與技術(shù),2017 (26):104-107