梁 曉,龍 妍,張 川
(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技術對傳統物聯網服務器架構進行解耦,設計和實現了一種高擴展性物聯網服務器架構。使物聯網系統具有分布式系統的橫向擴展性,滿足中小型物聯網企業對產品研發和運營的要求,為靈活地接入多種物聯網終端設備及與第三方平臺聯運提供保障。該架構已接入智能路燈、智能充電樁、智能安檢門等多種終端設備,并與第三方智慧城市管理系統和充電平臺進行了數據對接,整個系統在生產環境中運行狀態良好,達到了設計目標。