葉 標, 馮 拔, 李 祥
(1.長沙中車智馭新能源科技有限公司, 長沙 410083; 2.中車時代電動汽車股份有限公司, 湖南 株洲 412007)
隨著新能源車輛持續(xù)增漲[1],為滿足GB/T 32960.3—2016 《電動汽車遠程服務與管理系統(tǒng)技術規(guī)范 第3部分:通訊協(xié)議及數(shù)據(jù)格式》和國家及地方對新能源客車數(shù)據(jù)進行實時監(jiān)管的要求,各車企紛紛搭建自己的車輛數(shù)據(jù)監(jiān)控平臺[2]。隨著平臺接入車輛數(shù)據(jù)體量和種類的逐年增長,以及為實現(xiàn)對車輛關鍵零部件數(shù)據(jù)的實時、不間斷采集,車輛數(shù)據(jù)發(fā)送頻率、流量也在不斷增加,使車輛監(jiān)管平臺面臨高并發(fā)壓力以及數(shù)據(jù)延時長等問題[3]。基于此,本文設計和實現(xiàn)一個能解決上述問題,同時還能提高業(yè)務處理能力、兼具更優(yōu)擴展性的車輛監(jiān)控平臺。
本文平臺通過CAN總線技術采集車輛數(shù)據(jù),基于Netty網(wǎng)絡應用程序架構[4]搭建通信網(wǎng)關,利用Netty架構異步非阻塞[5]、事件驅動等特性,解決大批量車載終端連接的高并發(fā)壓力,同時將耗時的數(shù)據(jù)處理工作綁定自定義線程池進行異步處理;復雜的數(shù)據(jù)處理業(yè)務交由SpringCloud微服務集群進行分布式處理,通過優(yōu)化線程池參數(shù)、自定義解碼和編碼方式、自定義通信協(xié)議,進一步提升平臺的高并發(fā)性和低時延性。
Netty 框架是基于Reactor模型[6]開發(fā)的,通過異步事件驅動和epoll I/O多路復寫技術實現(xiàn)終端設備的高并發(fā)接入,其模型如圖1所示。Netty服務端推薦采用主從多線程池模型,主線程池(BossGroup)和從線程池(WorkGroup)都是NioEventLoopGroup類型,主要功能是維護EventLoop子線程和Selector選擇器;EventLoop線程通過選擇器,輪詢與其綁定的Socket的網(wǎng)絡通信,并執(zhí)行處理任務。其中主線程池用來處理設備的連接,將建立的Socket信道注冊到WorkGroup線程池中NioEventLoop子線程中的Selector中,從而實現(xiàn)與Worker線程進行綁定。從線程池處理Socket信道數(shù)據(jù)讀寫,數(shù)據(jù)讀寫任務完成后,其他任務相繼根據(jù)注冊到NioServerSocketChannel的順序依次進行。當存在多個設備與服務器建立連接時,服務器通過Selector監(jiān)聽每個信道上是否需要進行讀寫。這種非阻塞的讀寫過程不僅能提升 I/O 線程的運行效率,同時能夠實現(xiàn)線程并發(fā)進行多個設備連接和數(shù)據(jù)讀寫操作。Netty服務端架構[7]包含Boss和Worker兩個事件循環(huán)組(NioEventLoopGroup),Boss組主要負責處理連接事件并將請求分發(fā)給Worker組,由Worker組負責IO讀寫和業(yè)務處理。

圖1 網(wǎng)關Netty模型圖
Kafka作為信息中間件模型[8]有兩種信息傳遞方式:點對點的傳遞模式和分布式的發(fā)布-訂閱模式。本文設計的監(jiān)控平臺包含多個數(shù)據(jù)處理業(yè)務,每個業(yè)務模塊包含一個消費者,符合多個消費者消費一個Topic的應用場景,因此本文使用分布式的發(fā)布-訂閱模式。
Kafka作為一個分布式的發(fā)布/訂閱信息傳遞的中間件模型,具有可擴展、高吞吐量、有序化、持久化等特性,常用于處理異步通信、應用解耦以及流量控制等問題。同時Kafka模型的分布式體現(xiàn)在Kafka采用集群的方式在多臺Kafka服務器上運行,并通過Zookeeper對集群進行管理[9],支持動態(tài)水平擴展,同一個Topic的消息可以存儲在不同的Partition分區(qū)來提高吞吐率。在消費者讀取信息時,每個分區(qū)為信息標記位置,并通過偏移量記錄當前消費信息的位置,從而保證每個Partition內(nèi)的信息有序。Kafka從底層看是一條信息隊列,并將存入隊列的信息數(shù)據(jù)進行持久化,在Kafka處理系統(tǒng)明確指出數(shù)據(jù)已經(jīng)被處理完之前,都可以將數(shù)據(jù)恢復,消費者通過請求Broke中轉站,從Topic中獲取數(shù)據(jù)。
CAN總線技術(ControllerArea Network)[10],作為廣泛應用在客車內(nèi)部控制器之間的通訊協(xié)議,具有通信及時性高、抗干擾強、傳輸誤碼率低、成本低等特點。多個控制模塊通過CAN控制器連接到CAN總線網(wǎng)絡,CAN總線通過廣播的方式,將其報文數(shù)據(jù)傳輸?shù)礁鱾€CAN模塊,每個報文具有8個字節(jié)長度和唯一標識符ID。同時車載終端設備通過兩根CAN總線連接到CAN總線網(wǎng)絡并獲取客車的電機、電池、電控三電數(shù)據(jù)以及其他相關零部件的控制信息。
基于SpringCloud的微服務架構[11]將車輛監(jiān)控平臺的不同功能模塊拆分成相互獨立的微服務應用,每個微服務應用專注于單一的業(yè)務功能。微服務應用又是基于SpringBoot架構搭建,相互之間通過輕量級Http協(xié)議進行通信,易于開發(fā)和運維。
本文設計的新能源客車數(shù)據(jù)監(jiān)管平臺,通過CAN總線技術采集整車關鍵零部件信息,基于Netty網(wǎng)絡通信開發(fā)架構和自定義編解碼方式,實現(xiàn)車載終端數(shù)據(jù)的采集與轉發(fā),實現(xiàn)終端到網(wǎng)關之間的可靠傳輸。引入Kafka信息中間件,基于其異步通信的特性提高網(wǎng)關的并發(fā)量;利用應用解耦的特性將數(shù)據(jù)流式處理模塊與存儲分析模塊和業(yè)務模塊進行解耦;基于B/S模式構建Web應用平臺對車輛數(shù)據(jù)進行監(jiān)測。平臺總體架構如圖2所示。新能源客車數(shù)據(jù)監(jiān)管平臺分為4個核心功能模塊。
1) 數(shù)據(jù)采集模塊。基于車載終端T-Box,通過CAN總線連接整車控制器,采集車輛電機、電池、電控的核心三電信息數(shù)據(jù),是轉發(fā)系統(tǒng)的數(shù)據(jù)來源。
2) 數(shù)據(jù)流式并發(fā)處理模塊。基于Netty服務端模型搭建的網(wǎng)關,通過Redis緩存終端設備與服務器之間的連接信息,可支持擴展GB 32960以外的其他設備通訊協(xié)議。終端與網(wǎng)關建立連接SocketChannel的信道,上傳采集數(shù)據(jù),終端上傳的數(shù)據(jù)為十六進制原始碼流,網(wǎng)關接收后存放在ByteBuf 緩沖對象中。在傳輸過程中,可能會發(fā)生TCP粘包的問題,針對此問題,通過自定義Decoder解碼器[9],解析數(shù)據(jù)中標志本包數(shù)據(jù)單元長度的對應字節(jié)位,將解析出來的數(shù)據(jù)長度與本包數(shù)據(jù)的實際長度進行對比,如果長度不夠,則通過重置ByteBuf索引位置,與下一包數(shù)據(jù)合并,直到讀取出滿足數(shù)據(jù)單元長度規(guī)定的完整的一包數(shù)據(jù),再將此包數(shù)據(jù)傳遞到下一個事務處理器(Handler)中。當有完整數(shù)據(jù)進入Handler時,首先對數(shù)據(jù)內(nèi)容進行解析,解析出終端對應的車架號、數(shù)據(jù)采集時間等字段組成關鍵字,然后通過調用Kafka的生產(chǎn)者(Producer)將數(shù)據(jù)存入Kafka中,再通過Flink流式計算技術對原始報文數(shù)據(jù)進行實時解析處理,并根據(jù)解析后數(shù)據(jù)特性進行分類,存入不同的數(shù)據(jù)集。
3) 數(shù)據(jù)存儲分析模塊。包含Hbase、Mysql、Redis數(shù)據(jù)庫,分別以集群的方式部署并通過Zookeeper進行監(jiān)管,其中Hbase存儲Flink計算后的數(shù)據(jù)集以及未處理的原始報文,采用HIVE、Hbase、Imapla結合的方式,配置HIVE與Hbase數(shù)據(jù)同步,通過Kettle工具進行數(shù)據(jù)清洗,并基于ElasticSearch進行建模分析。 Redis集群存儲實時性要求較高的報文信息,如實時報警信息、車輛定位信息等。Mysql集群用于存儲大數(shù)據(jù)分析過后生成的預警信息和運營統(tǒng)計報表信息。
4) 業(yè)務處理模塊。基于SpringCloud架構開發(fā),單個應用服務又是基于Springboot架構,通過集成大量的框架,并盡可能地自動配置Spring,以簡化整個項目的搭建和開發(fā)過程。各服務之間使用RESTFUL API相互協(xié)調,通過Eureka注冊中心獲取和管理服務,通過Ribbon維持各個分布式服務器間的負載均衡,通過Hystrix熔斷機制保護微服務鏈路。前端使用Vue架構,基于MVVM[12](Model View ViewModel)的模式,實現(xiàn)后端傳遞數(shù)據(jù)與前端頁面的雙向綁定。將項目使用到的前端靜態(tài)資源如js、css等單獨存放在靜態(tài)資源服務器上由前端維護,從而實現(xiàn)前后端分離。業(yè)務處理模塊的主要功能有:

圖2 系統(tǒng)總體架構圖
①車輛行駛狀態(tài)監(jiān)控。車輛通過終端與平臺建立通信連接后,平臺用戶可以對車輛實時行駛狀態(tài)數(shù)據(jù)進行監(jiān)控。通過WebSocket客戶端處理上傳數(shù)據(jù)并發(fā)送給WebSocket服務器,再通過WebSocket服務器實時推送給平臺。
②預警信息推送。平臺通過大數(shù)據(jù)建模對車輛關鍵數(shù)據(jù)進行分析、判斷,如車輛上傳數(shù)據(jù)達到預警閾值,則按照特定的規(guī)則生成預警信息,并通過語音、短信、APP的方式推送給車輛相關負責人。
③遠程控制。車輛通過終端與平臺建立通信連接后,平臺用戶可以對車輛下發(fā)控制指令,通過獲取終端設備與Netty網(wǎng)關服務器間的連接信息,然后根據(jù)控制信息內(nèi)容封裝成原始碼流,再通過Netty網(wǎng)關下發(fā)給車載終端,從而實現(xiàn)車輛遠程控制。
④生成統(tǒng)計報表。根據(jù)大數(shù)據(jù)模型生成車輛運營里程統(tǒng)計報表、故障統(tǒng)計報表、累計能耗統(tǒng)計等信息,平臺通過設置統(tǒng)計時間緯度生成統(tǒng)計報表,同時支持報表導入導出。
基于Netty 服務端框架開發(fā)與設備進行通信的網(wǎng)關,通過異步事件驅動實現(xiàn)終端設備的高并發(fā)接入。終端與網(wǎng)關建立連接后,開始接收終端上傳的數(shù)據(jù),數(shù)據(jù)通過服務端非阻塞 I/O 模型的 Socket 通道進行讀寫,數(shù)據(jù)讀寫任務完成后,其他任務根據(jù)注冊在SocketChannel的順序依次進行。這種非阻塞的讀寫過程不僅能提升 I/O 線程的運行效率,同時能實現(xiàn)線程并發(fā)進行多個連接的和數(shù)據(jù)讀寫操作。
Netty的服務端架構在處理設備連接以及I/O讀寫處理后會觸發(fā)ChannelPipeline中的自定義Handler線程池,通過異步的方式進行終端設備信息鑒權、消息回復等業(yè)務處理,同時根據(jù)消息類型將數(shù)據(jù)存入不同的Topic中,由后續(xù)微服務業(yè)務線程消費數(shù)據(jù)進行業(yè)務流程,數(shù)據(jù)處理流程如圖3所示。

圖3 數(shù)據(jù)處理流程圖
在本文設計的平臺中,終端與Netty服務端之間以國標GB/T 32960協(xié)議作為通信協(xié)議傳輸國標數(shù)據(jù),協(xié)議格式見表1;并基于此協(xié)議擴展了企標數(shù)據(jù)通訊傳輸協(xié)議,協(xié)議格式見表2。表2中的企標數(shù)據(jù)包數(shù)據(jù)結構封裝在表1國標協(xié)議數(shù)據(jù)包中的數(shù)據(jù)單元部分。兩種協(xié)議都是以TCP/IP網(wǎng)絡控制協(xié)議作為底層通信承載協(xié)議。數(shù)據(jù)接收端在接收到傳輸數(shù)據(jù)后應先對數(shù)據(jù)格式進行判斷,如果符合協(xié)議格式要求,則進行數(shù)據(jù)業(yè)務處理;如果不符合則丟棄數(shù)據(jù),并斷開連接。

表1 國標協(xié)議數(shù)據(jù)包結構

表2 企標數(shù)據(jù)包數(shù)據(jù)結構
為進一步提升轉發(fā)系統(tǒng)的性能,本文通過以下措施進行優(yōu)化:
1) 將數(shù)據(jù)解析、持久化等耗時操作,加入異步線程池。
2) 通過自定義Handler 并將其分配到獨立的線程池,然后將線程池以及Handler添加到ChannelPipeline容器中,實現(xiàn)Handler的自定義線程池與WorkGroup線程池完全分離,從而最大限度避免長時間程序阻塞。同時自定義線程池的大小,設置最大線程數(shù)N的參考算法[13]如下:
N=Ncpu×Ucpu×(1+W/C)
式中:Ncpu為核心CPU數(shù)目,通過Runtime.getRuntime().availableProcessors() 獲得;Ucpu為CPU使用率,一般設為1;W為線程阻塞時間;C為線程計算時間。
本文自定義線程屬于計算密集型線程,結合實際運行環(huán)境,設置N為Ncpu+1。
3) 調整Netty服務端與客戶端的參數(shù)設置:設置TCP_NODELAY來關閉nagle算法,避免數(shù)據(jù)包堆積,從而降低延遲;設置SO_RCVBUF、SO_SNDBUF來調整接收方和發(fā)送方的收發(fā)緩存區(qū)大小,避免擁堵。
使用Jmeter模擬車載終端設備以10 s一包的頻率向網(wǎng)關發(fā)送報文。通過設置并發(fā)線程數(shù)為3 000,輪發(fā)請求間隔為10 s,重復30次,然后在網(wǎng)關程序中定義一個計數(shù)器,統(tǒng)計所有連接的通道數(shù)。測試結果如圖4所示:當并發(fā)量為3 000時,通過對30次試驗取平均值,本文采用的自定義編碼解碼方式網(wǎng)關與采用傳統(tǒng)Java序列化的網(wǎng)關每秒最大接入量分別為2 047臺和1 868臺,相較之下基于自定義編碼的網(wǎng)關接入量提升了9%左右。

自定義Handler時將解析數(shù)據(jù)寫入Kafka的Topic中,統(tǒng)計不同并發(fā)量下300 s內(nèi)存入Topic中的數(shù)據(jù)量作為事物處理總數(shù)(簡稱TC),將TC作為通信性能測試的結果,其統(tǒng)計數(shù)如圖5所示,處理請求效率平均提升30%左右。

圖5 通信性能統(tǒng)計圖
使用Postman設置Monitor監(jiān)控任務對Web應用平臺接口的響應時間,并以視圖的形式展示接口響應時間的測試結果。對Web應用平臺接口進行單次6 h的監(jiān)控,共計20次,監(jiān)控平均響應時間為0.74 s,傳統(tǒng)平臺接口平均響應時間為0.8 s,相較之下,平均響應速度提高了8%左右,部分Web平臺響應測試結果如圖6所示。

圖6 Web應用平臺響應測試統(tǒng)計圖
本文提出了一種新能源客車數(shù)據(jù)監(jiān)管平臺設計方法,解決了監(jiān)控平臺在實際生產(chǎn)環(huán)境中面臨的高并發(fā)壓力和數(shù)據(jù)延時長的問題,提升了平臺業(yè)務處理能力和接口請求響應速率,適用于包含GB/T 32960和企標的多種協(xié)議,滿足企業(yè)日常監(jiān)管新能源客車上傳數(shù)據(jù)業(yè)務需求的同時,具有較好的擴展性。