任培花,李健浩
(山西大同大學(xué) 計(jì)算機(jī)與網(wǎng)絡(luò)工程學(xué)院,山西 大同 037009)
車輛稽查[1]是指,通過道路執(zhí)法系統(tǒng)對過往車輛信息的實(shí)時(shí)采集,并將拍攝日志實(shí)時(shí)傳回交警指揮中心的服務(wù)器進(jìn)行存儲,然后對海量日志數(shù)據(jù)進(jìn)行處理,從中找出嫌疑車輛。
傳統(tǒng)的車輛稽查方式應(yīng)對日益上漲的交通執(zhí)法壓力顯得力不從心,尤其面對海量信息,采用人工或半人工的稽查處理方式不僅費(fèi)時(shí)費(fèi)力,而且滯后嚴(yán)重,這些情況說明傳統(tǒng)的車輛稽查方式顯然是不合理的。因此,在海量車輛信息和日志信息的大背景下,如何降低車輛違法行為的稽查壓力,是當(dāng)前急需解決的問題。
關(guān)于車輛稽查系統(tǒng)的研究國內(nèi)起步較晚,是隨著汽車保有量的增長,車輛各種違法行為(違法行駛、遮擋拍照、套牌等)增多的現(xiàn)狀推動(dòng)下,對車輛稽查系統(tǒng)問題的研究才逐漸開始的。很多學(xué)者都是借助物聯(lián)網(wǎng)進(jìn)行采集,然后直接將數(shù)據(jù)保存、后期分析的方法開展研究。文中減少了對物聯(lián)網(wǎng)技術(shù)的依賴,以稽查數(shù)據(jù)研究為重點(diǎn),借助大數(shù)據(jù)技術(shù)[2],提出一種交通運(yùn)行數(shù)據(jù)模擬方案。在具體技術(shù)實(shí)現(xiàn)方面,在前人研究地基礎(chǔ)上,進(jìn)行了一系列創(chuàng)新。如江日念等提出將Maven應(yīng)用到Java項(xiàng)目中[3],文中借鑒該方法將Maven引入仿真系統(tǒng)進(jìn)行橫向和縱向拆分,提高代碼的魯棒性及團(tuán)隊(duì)開發(fā)下的易管理性;邱祝文從系統(tǒng)應(yīng)用角度出發(fā),提出基于Redis的分布式緩存系統(tǒng)架構(gòu)[4],在該研究的基礎(chǔ)上合理使用Redis集群,完成攝像頭拍攝模擬模塊的設(shè)計(jì),并結(jié)合Flume框架[5-7]保證分布式日志穩(wěn)定可靠收集的需求;薛亞鵬提出“基于實(shí)時(shí)日志系統(tǒng)的海量日志服務(wù)平臺設(shè)計(jì)與實(shí)現(xiàn)”[8],魏彬提出“基于分布式日志系統(tǒng)的數(shù)據(jù)云服務(wù)平臺設(shè)計(jì)與實(shí)現(xiàn)”[9],均為日志收集提供思路,具體實(shí)現(xiàn)過程選用穩(wěn)定可靠的Hadoop[10-14]框架完成日志收集。
根據(jù)高并發(fā)模擬[15-16]下計(jì)算機(jī)性能充分利用原則,以功能對計(jì)算機(jī)資源消耗程度為度量對項(xiàng)目進(jìn)行橫向和縱向的拆分,將系統(tǒng)劃為4個(gè)模塊:交通元素模擬模塊、車輛模擬運(yùn)行模塊、攝像頭拍攝模擬模塊和日志收集模塊,通過不同模塊在不同服務(wù)器中的部署運(yùn)行完成各自的功能。以下為系統(tǒng)各功能模塊分析說明。
城市交通元素模擬模塊是該系統(tǒng)的基礎(chǔ)模塊,將從需求分析、輸入和輸出進(jìn)行闡述。
(1)需求分析。
該模塊對城市交通運(yùn)行中的“城市”、“交通卡口”、“攝像頭”、“機(jī)動(dòng)車”四個(gè)交通元素的模擬進(jìn)行需求分析。表1是對該模塊的需求劃分。
表1 城市交通元素模擬模塊
(2)輸入和輸出。
系統(tǒng)出于性能考慮對項(xiàng)目進(jìn)行橫向和縱向的拆分,拆分后該模塊主要負(fù)責(zé)對系統(tǒng)中實(shí)體類的抽象,沒有具體的數(shù)據(jù)輸入和輸出。
車輛模擬運(yùn)行模塊是系統(tǒng)的核心模塊之一,將從需求分析、輸入和輸出兩個(gè)角度展開闡述。
(1)需求分析。
車輛模擬運(yùn)行即對現(xiàn)實(shí)生活中城市道路上20萬輛機(jī)動(dòng)車同時(shí)運(yùn)行過程的模擬。系統(tǒng)中,該模塊需要對現(xiàn)實(shí)城市中道路中的車輛對象進(jìn)行模擬,合理地將20萬輛車分布到所有街道中,并對車輛在道路中的實(shí)時(shí)隨機(jī)行駛及進(jìn)過卡口這一事件進(jìn)行模擬,同時(shí)保證20萬級別的超高并發(fā)度,實(shí)現(xiàn)對現(xiàn)實(shí)生活中20萬輛車在城市道路中并發(fā)行駛的模擬。表2為車輛模擬運(yùn)行模塊的需求劃分。
表2 車輛模擬運(yùn)行模塊需求劃分
(2)輸入和輸出
該模塊以20萬輛機(jī)動(dòng)車基本信息、2 000個(gè)卡口基本信息為模塊輸入值,以攜帶有車輛懸掛牌照、車輛運(yùn)行方向、經(jīng)過卡口的位置等信息的海量級車輛行駛?cè)罩緸檩敵鲋怠?/p>
攝像頭拍攝模擬模塊是系統(tǒng)的核心模塊之一,將從需求分析、輸入和輸出兩個(gè)角度展開闡述。
(1)需求分析。
攝像頭拍攝模擬即對現(xiàn)實(shí)生活中監(jiān)控?cái)z像頭拍攝經(jīng)過車輛的信息過程的模擬。在系統(tǒng)中,該模塊負(fù)責(zé)對上層模塊發(fā)來的短時(shí)間海量的車輛行駛?cè)罩具M(jìn)行處理,從車輛行駛?cè)罩局蝎@取車輛所經(jīng)過的卡口位置信息,最終獲取所拍攝的攝像頭信息并追加到車輛行駛?cè)罩局?,成為攝像頭拍攝日志,完成對現(xiàn)實(shí)生活中攝像頭抓拍經(jīng)過卡口的車輛牌照、抓拍時(shí)間、車輛行駛速度等拍攝過程的模擬。表3為攝像頭拍攝模擬模塊的需求劃分。
表3 攝像頭拍攝模擬模塊需求劃分
(2)輸入和輸出。
該模塊以上層模塊傳來的攜帶有車輛懸掛牌照、車輛運(yùn)行方向、經(jīng)過卡口的位置等信息的海量級車輛行駛?cè)罩炯癛edis中相應(yīng)的攝像頭對象JSON數(shù)組為輸入值,以攜帶有車輛懸掛牌照、車輛運(yùn)行方向、拍攝地點(diǎn)、拍攝時(shí)間、卡口id、卡口位置信息、攝像頭id、攝像頭基本信息等要素的攝像頭拍攝日志為輸出值。
日志收集模塊是系統(tǒng)的核心模塊之一,將從需求分析、輸入和輸出兩個(gè)角度展開闡述。
(1)需求分析。
該模塊負(fù)責(zé)對上層模塊(分布式集群)發(fā)來的海量級的日志數(shù)據(jù)進(jìn)行高效、可靠的收集及在分布式文件系統(tǒng)中的合理可靠存儲。表4為日志收集模塊的需求劃分。
表4 日志收集模擬需求劃分
(2)輸入和輸出。
該模塊以上層模塊(分布式集群)傳來的日志數(shù)據(jù)為輸入值,以分布式文件系統(tǒng)中日志文件為輸出值。
結(jié)合系統(tǒng)需求分析及項(xiàng)目架構(gòu)設(shè)計(jì)對系統(tǒng)整體進(jìn)行網(wǎng)絡(luò)架構(gòu)設(shè)計(jì)。系統(tǒng)網(wǎng)絡(luò)架構(gòu)如圖1所示。
圖1 車輛模擬運(yùn)行及日志收集子系統(tǒng)網(wǎng)絡(luò)架構(gòu)
根據(jù)各個(gè)Maven子項(xiàng)目和各個(gè)模塊的特點(diǎn),將車輛模擬運(yùn)行項(xiàng)目獨(dú)立部署在一臺服務(wù)器,使服務(wù)器性能得到最大發(fā)揮。由于攝像頭拍攝模擬模塊要抗擊上層車輛模擬運(yùn)行模塊發(fā)來的海量級Http壓力的特點(diǎn),將攝像頭拍攝模擬項(xiàng)目分別部署在三臺服務(wù)器上,結(jié)合Ngnix服務(wù)器的使用,實(shí)現(xiàn)負(fù)載均衡的效果,抗擊上層模塊超高并發(fā)的http請求,保證攝像頭拍攝模擬的性能。根據(jù)攝像頭拍攝模擬模塊高頻率進(jìn)行數(shù)據(jù)庫IO操作的特點(diǎn),使用Redis(內(nèi)存級數(shù)據(jù)庫)并結(jié)合哨兵及分片機(jī)制來保障攝像頭拍攝模擬服務(wù)器集群高頻率的數(shù)據(jù)庫IO操作。Redis集群架構(gòu)如圖2所示。
圖2 Redis集群架構(gòu)
考慮到攝像頭拍攝模擬模塊分布式集群的特點(diǎn),選用Flume并采取多級流動(dòng)的結(jié)構(gòu)保證攝像頭拍攝模擬模塊分布式日志穩(wěn)定可靠收集的需求。在存儲方面,考慮到該系統(tǒng)分布式集群輸出海量級別的日志的特點(diǎn),選用穩(wěn)定可靠的Hadoop[8-12]集群(3臺),并將日志文件存儲在分布式文件系統(tǒng)上。Flume[14-16]及Hadoop架構(gòu)設(shè)計(jì)如圖3所示。
圖3 Flume及Hadoop架構(gòu)設(shè)計(jì)
針對該系統(tǒng)的關(guān)鍵功能模塊給出具體的實(shí)現(xiàn)方式。
車輛模擬運(yùn)行功能即對20萬輛車在道路中實(shí)時(shí)運(yùn)行進(jìn)行模擬。涉及的類包括RunController類、CarTask類、HttpClientThread類、HttpThreadFactory類、SystemConfig類、Car類、HttpClientService類、Position類等。
(1)RunController類。
負(fù)責(zé)車輛模擬運(yùn)行的準(zhǔn)備工作,包括Runnable任務(wù)創(chuàng)建、線程池創(chuàng)建等。由于車輛模擬運(yùn)行功能的性能完全取決于線程并發(fā)性能及合理的調(diào)度,針對高并發(fā)的要求,對線程、線程池、對象復(fù)用做了專門的設(shè)計(jì)。由于篇幅原因,這里只對高并發(fā)需求下的線程相關(guān)設(shè)計(jì)的實(shí)現(xiàn)進(jìn)行描述。
(2)CarTask類。
實(shí)現(xiàn)自Runnable接口,為每一輛車創(chuàng)建一個(gè)CarTask對象,在run()方法中,執(zhí)行對應(yīng)的Car類對象的move方法,模擬車輛行駛一步。同時(shí),根據(jù)move()方法返回的信息判斷車輛當(dāng)前步驟是否經(jīng)過了卡口,如經(jīng)過卡口,則使用當(dāng)前線程中的HttpClient對象,向下層模塊發(fā)送車輛行駛?cè)罩?。日志格式如下?/p>
①內(nèi)容。
車輛id|真實(shí)車牌|懸掛車牌|當(dāng)前拍攝時(shí)的坐標(biāo)_X|當(dāng)前拍攝時(shí)的坐標(biāo)_Y|車輛上一步坐標(biāo)_X|車輛上一步坐標(biāo)_Y|拍攝時(shí)運(yùn)行方向|車輛被拍攝的坐標(biāo)_X|車輛被拍攝的坐標(biāo)_Y|拍攝時(shí)間(long)|拍攝的攝像頭id
②編碼。
id|registId|hangId|x|y|prex|prey|dir|passedPortPosition_X|passedPortPosition_X|timestamp|sensorId
HttpClientThread類是為解決20萬級的數(shù)量下HttpClient對象的復(fù)用而設(shè)計(jì)的自定義線程類。將HttpClient對象從CarTask中抽出,封裝在了每個(gè)線程中,大大提高了對象的復(fù)用及項(xiàng)目穩(wěn)定性。
ScheduledExecutorService屬性(RunController類屬性)是為了針對車輛需要循環(huán)執(zhí)行行駛步驟的要求而選用Excutors框架中的定時(shí)調(diào)度線程池類對象。
addTasksToPoll()方法是將200 000個(gè)Runnable任務(wù)(CarTask)提交至線程池,線程池會(huì)定時(shí)將任務(wù)隊(duì)列中的隊(duì)列提交給線程執(zhí)行,保證每個(gè)任務(wù)執(zhí)行的間隔相同。
至此,每個(gè)車輛以一定的時(shí)間間隔執(zhí)行一步模擬行駛,如果經(jīng)過卡口,則向下層模塊發(fā)送車?yán)镄旭側(cè)罩?。車輛運(yùn)行模塊涉及所有功能均已實(shí)現(xiàn)。
攝像頭拍攝模擬模塊具體包括卡口模擬、攝像頭模擬、攝像頭拍攝模擬三個(gè)功能。以下將從這三個(gè)功能展開介紹。
(1)卡口及攝像頭模擬。
由于攝像頭拍攝模擬模塊采用分布式集群架構(gòu),攝像頭拍攝模擬模塊需要高效的根據(jù)上層模塊傳來行駛中車輛經(jīng)過的卡口位置信息高效獲取到對應(yīng)的攝像頭信息,因此選用內(nèi)存級數(shù)據(jù)庫Redis,搭配哨兵及分片機(jī)制搭建本功能。同時(shí)將100 000臺攝像頭中位置相同的攝像頭合并為一個(gè)集合,以位置信息為鍵,集合為值的形式存儲在內(nèi)存級數(shù)據(jù)庫Redis集群中。
(2)攝像頭拍攝模擬。
攝像頭拍攝模擬功能即攝像頭拍攝模擬模塊接收上層發(fā)送的車輛行駛?cè)罩荆鶕?jù)日志中的位置信息從Redis中獲取相應(yīng)的攝像頭信息追加到日志中,成為拍攝日志,發(fā)送給下層模塊。拍攝模擬功能時(shí)序如圖4所示。
MessageHandlerController.handle(String carRunInfo)方法負(fù)責(zé)接收到來自上層模塊傳來的車輛行駛?cè)罩?,提取出車輛經(jīng)過的卡口位置信息,內(nèi)部調(diào)用MessageHandlerServiceImpl類對象的getSensorIDByPocation(Position pos)方法根據(jù)位置信息獲取拍攝的攝像頭id。
MessageHandlerServiceImpl.getSensorIDByPocation(Position pos)負(fù)責(zé)攝像頭拍攝模擬的具體實(shí)現(xiàn),內(nèi)部通過JedisCluster實(shí)現(xiàn)類與Redis進(jìn)行相應(yīng)的通信。
圖4 拍攝模擬功能時(shí)序
jedisCluster.smembers()方法負(fù)責(zé)和Redis集群進(jìn)行交互,借助本方法根據(jù)位置信息獲取所有該位置上所有的攝像頭的JSON格式字符串。從獲取到的集合中隨機(jī)選中一個(gè)攝像頭對象JSON字符串,并提取攝像頭id返回。
日志收集模塊即對分布式的攝像頭拍攝模擬集群產(chǎn)生的海量日志信息進(jìn)行穩(wěn)定可靠的收集,具體分為分布式日志收集和海量日志文件分布式存儲兩部分。分布式日志收集部分采用現(xiàn)階段成熟的Flume分布式日志收集框架進(jìn)行功能的搭建,采用多級流動(dòng)的形式提高上層拍攝模塊高并發(fā)情況下的收集性能。海量日志分布式存儲部分采用成熟的Hadoop生態(tài)系統(tǒng)中HDFS分布式文件系統(tǒng)來實(shí)現(xiàn)。由于篇幅原因,對Hadoop集群搭建過程不做描述。
借助大數(shù)據(jù)技術(shù),該系統(tǒng)的研究和實(shí)現(xiàn),不僅實(shí)現(xiàn)了城市級別的車輛模擬運(yùn)行和日志收集,可以為城市交通提供完整、相對貼合實(shí)際的運(yùn)行場景,而且以此模擬系統(tǒng)為依據(jù),可以方便車輛稽查,甚至調(diào)整道路交通運(yùn)行方案。該系統(tǒng)為數(shù)據(jù)量較大的行業(yè)提供了一種解決問題的思路,用同樣的方法可以為城市旅游、城市產(chǎn)業(yè)分布等進(jìn)行模擬,進(jìn)而調(diào)整旅游服務(wù)、產(chǎn)業(yè)設(shè)置等方案。