李洪昌+周磊
摘 要:針對(duì)目前傳統(tǒng)媒體發(fā)布形式制作成本高、內(nèi)容模式固化,且市場(chǎng)上已有的多媒體發(fā)布系統(tǒng)性能單一,維護(hù)成本高,無(wú)法統(tǒng)一發(fā)布并規(guī)范管理的弱點(diǎn),文中采用Python語(yǔ)言和Django框架開發(fā)了一套具有實(shí)時(shí)監(jiān)控和精準(zhǔn)推送的多媒體信息發(fā)布系統(tǒng),充分利用了Python簡(jiǎn)潔、易擴(kuò)展和Django方便、快速的特點(diǎn),較好地改進(jìn)了傳統(tǒng)媒體的弊端。通過(guò)線上部署實(shí)際使用,證明了本系統(tǒng)在一萬(wàn)臺(tái)以上設(shè)備同時(shí)在線的高并發(fā)情況下依然能夠?qū)崿F(xiàn)終端精確監(jiān)控和視頻精準(zhǔn)推送。
關(guān)鍵詞:終端監(jiān)控;Django;Python;精準(zhǔn)推送
中圖分類號(hào):TP393 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2095-1302(2018)02-00-03
0 引 言
隨著多媒體技術(shù)的不斷發(fā)展,各行各業(yè)都受到了沖擊,傳媒行業(yè)亦如此。將多媒體技術(shù)應(yīng)用于廣告播放的多媒體系統(tǒng)應(yīng)運(yùn)而生,這種用于播放視頻廣告的多媒體機(jī)現(xiàn)已廣泛應(yīng)用于各大賣場(chǎng),直觀地向人們傳遞需要的信息。然而,現(xiàn)有的媒體發(fā)布系統(tǒng)主要仍以本地存儲(chǔ)和離線系統(tǒng)為主[1,2],無(wú)法由后臺(tái)進(jìn)行實(shí)時(shí)遠(yuǎn)程管理,維護(hù)成本高。
針對(duì)目前主流媒體廣告機(jī)在使用中存在的缺點(diǎn),基于Python的Django框架設(shè)計(jì)實(shí)現(xiàn)了一種多媒體發(fā)布系統(tǒng),只要能訪問(wèn)互聯(lián)網(wǎng),就可以直接對(duì)分布在全國(guó)各地的終端進(jìn)行監(jiān)控、管理和多媒體精準(zhǔn)推送,實(shí)現(xiàn)集中、實(shí)時(shí)的精確管理。
本系統(tǒng)采用Python語(yǔ)言和Django框架搭建了一個(gè)完整的Web平臺(tái)。Python是目前最流行的編程語(yǔ)言之一。Django是Python語(yǔ)言編寫的最優(yōu)秀的Web框架之一,采用的MVC框架模式[3]具有易開發(fā),便于更新維護(hù),移植性好等優(yōu)點(diǎn)。
1 系統(tǒng)總體設(shè)計(jì)
1.1 Django框架
Django使用Python語(yǔ)言編寫,遵循MVC的設(shè)計(jì)架構(gòu),但在具體實(shí)現(xiàn)上,會(huì)以自己特有的MTV模式體現(xiàn)出來(lái),即Models(模型),Template(模板),View(視圖)。
Django的項(xiàng)目結(jié)構(gòu)主要由Urls.py,Views.py,Models.py組成,其中Urls.py為整個(gè)項(xiàng)目的路由表,當(dāng)使用者訪問(wèn)特定的url時(shí),Urls.py將請(qǐng)求指向Views.py(視圖函數(shù))中特定的函數(shù),在視圖函數(shù)中與數(shù)據(jù)模型進(jìn)行一系列交互操作來(lái)響應(yīng)用戶的請(qǐng)求。Urls.py和Views.py可由MVC中的控制器即Controller來(lái)描述[4]。
Django的模式如圖1所示。
1.2 系統(tǒng)結(jié)構(gòu)設(shè)計(jì)
系統(tǒng)采用分層設(shè)計(jì),可分為表示層,業(yè)務(wù)邏輯層和數(shù)據(jù)訪問(wèn)層,如圖2所示。分層設(shè)計(jì)使得系統(tǒng)具有高內(nèi)聚,低耦合的特點(diǎn),當(dāng)改變針對(duì)用戶的表現(xiàn)層設(shè)計(jì)時(shí),不會(huì)影響底層的業(yè)務(wù)邏輯和數(shù)據(jù)訪問(wèn),同樣,當(dāng)改變底層結(jié)構(gòu)時(shí),只要提供給上層的JSON數(shù)據(jù)接口不變,則不會(huì)對(duì)表現(xiàn)層產(chǎn)生任何影響。三層結(jié)構(gòu)使得系統(tǒng)的各模塊獨(dú)立性比較強(qiáng),有利于系統(tǒng)的維護(hù)、升級(jí),易于資源的分配,降低了開發(fā)和運(yùn)維成本。Django層使得整個(gè)App應(yīng)用獨(dú)立于項(xiàng)目,可隨時(shí)移植[4]。
1.3 系統(tǒng)功能需求
通過(guò)分析市面上的多媒體機(jī)功能,考慮合作公司的需求后,將系統(tǒng)功能需求分為6部分,分別為設(shè)備使用者的信息管理,終端設(shè)備的管理,媒體文件的上傳管理,節(jié)目的精準(zhǔn)推送,播放數(shù)據(jù)統(tǒng)計(jì),系統(tǒng)使用者信息管理。在功能設(shè)計(jì)方面,每部分又可分為多個(gè)子模塊。
1.4 系統(tǒng)功能設(shè)計(jì)
根據(jù)多媒體發(fā)布系統(tǒng)的功能需求分析,該系統(tǒng)由6個(gè)功能模塊組成。分別為客戶管理、終端設(shè)備管理、媒體管理、節(jié)目單管理、媒體播放數(shù)據(jù)統(tǒng)計(jì)、賬戶管理,系統(tǒng)功能如圖3所示。
客戶管理分為客戶信息管理、商店管理、代理商管理三個(gè)子模塊,客戶、代理商和商店具有上下級(jí)關(guān)系,即一個(gè)客戶有多個(gè)代理商,一個(gè)代理商有多個(gè)商店。每個(gè)子模塊分別負(fù)責(zé)該模塊信息的錄入、修改、刪除以及查詢下屬組織的信息。
終端管理分為終端信息管理、設(shè)備監(jiān)控、地圖模式、數(shù)據(jù)上傳四個(gè)子模塊,是系統(tǒng)的核心之一。終端信息管理模塊負(fù)責(zé)終端信息的添加、修改、刪除以及終端的初始化與該終端下的節(jié)目信息查詢;數(shù)據(jù)上傳模塊可以上傳表格文件在系統(tǒng)批量生成終端信息;設(shè)備監(jiān)控模塊和地圖模式分別以不同的方式使管理員直觀看到全網(wǎng)的設(shè)備狀況。
媒體管理分為媒體上傳和媒體管理兩個(gè)子模塊,媒體的制作和管理是媒體發(fā)布的重要環(huán)節(jié)。
節(jié)目單管理分為四個(gè)子模塊,分別為添加節(jié)目單、節(jié)目單管理、定點(diǎn)推送與默認(rèn)節(jié)目單,其中定點(diǎn)推送與默認(rèn)節(jié)目單是媒體發(fā)布的核心之一。
數(shù)據(jù)統(tǒng)計(jì)模塊分為終端數(shù)據(jù)統(tǒng)計(jì)、客戶數(shù)據(jù)統(tǒng)計(jì)、詳細(xì)數(shù)據(jù)統(tǒng)計(jì)三個(gè)子模塊,分別為不同層次的媒體播放數(shù)據(jù)統(tǒng)計(jì)。
賬戶管理模塊分為添加用戶和用戶管理兩個(gè)子模塊,為系統(tǒng)添加除管理員外的其他用戶和賦予其相應(yīng)的權(quán)限。
2 系統(tǒng)詳細(xì)實(shí)現(xiàn)
系統(tǒng)的核心設(shè)計(jì)主要分為終端監(jiān)控部分和視頻推送部分。其核心設(shè)計(jì)主要包括業(yè)務(wù)邏輯實(shí)現(xiàn)、前端界面實(shí)現(xiàn)和數(shù)據(jù)庫(kù)設(shè)計(jì)。業(yè)務(wù)邏輯基于Django框架,采用Python語(yǔ)言編寫。Python是一種面向?qū)ο蟮慕忉屝驼Z(yǔ)言,具有豐富強(qiáng)大的庫(kù),可以方便調(diào)用其他語(yǔ)言寫成的模塊(如C/C++),并將其他語(yǔ)言的優(yōu)勢(shì)集中起來(lái)。
前端展示界面采用jQuery和Bootstrap。jQuery是一個(gè)快速、簡(jiǎn)潔的JavaScript框架,Bootstrap是一個(gè)CSS/HTML框架,他們使用方便,效果多樣,結(jié)合Ajax技術(shù)便能夠營(yíng)造出一個(gè)完美的用戶體驗(yàn)界面,大大方便了用戶和系統(tǒng)的交互。
數(shù)據(jù)庫(kù)采用MySQL。MySQL是目前最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)之一,關(guān)系型數(shù)據(jù)庫(kù)用不同的二維表來(lái)存儲(chǔ)數(shù)據(jù),增加了存儲(chǔ)速度并提高了靈活性。MySQL體積小、速度快、源碼開放,已成為中小型網(wǎng)站的不二選擇。在Django中用MySQLdb模塊來(lái)驅(qū)動(dòng)MySQL,在項(xiàng)目中編寫Python類,使用ORM映射來(lái)操作數(shù)據(jù)庫(kù)表。endprint
2.1 終端監(jiān)控實(shí)現(xiàn)
在整個(gè)媒體發(fā)布系統(tǒng)中,有成千上萬(wàn)臺(tái)終端在運(yùn)行,一旦終端發(fā)生故障,那么后果不可預(yù)料,將對(duì)使用者和供應(yīng)商造成不可避免的損失,因此需要對(duì)所有終端進(jìn)行有效的監(jiān)控。如圖4所示,終端監(jiān)控在系統(tǒng)中處于核心環(huán)節(jié)。
系統(tǒng)采取心跳機(jī)制以保障監(jiān)控終端順暢運(yùn)行,即終端每隔5 s便發(fā)一次請(qǐng)求表明自己的狀態(tài),但由于系統(tǒng)中運(yùn)行的設(shè)備數(shù)量龐大,如此高頻度的請(qǐng)求對(duì)服務(wù)器造成了巨大的壓力,因此利用Python善于處理數(shù)據(jù)的優(yōu)勢(shì),將數(shù)據(jù)信息存儲(chǔ)在內(nèi)存中,自定義Sync函數(shù),通過(guò)Linux系統(tǒng)的Crontab機(jī)制每30 min調(diào)用一次Sync函數(shù)將內(nèi)存中的數(shù)據(jù)寫進(jìn)數(shù)據(jù)庫(kù)。查詢終端的狀況時(shí),如果從內(nèi)存中查到該終端信息,則渲染到前端,否則,從數(shù)據(jù)庫(kù)中取出數(shù)據(jù)。
終端設(shè)備向服務(wù)器發(fā)送的心跳請(qǐng)求以Http傳輸,接口協(xié)議為自定義的JSON格式。系統(tǒng)接到請(qǐng)求后,在項(xiàng)目中構(gòu)建一個(gè)Python類TerminalManager,所有與終端監(jiān)控相關(guān)的方法均定義在該類中。該類基于Python的基類Object,在構(gòu)造函數(shù)中定義了一個(gè)字典對(duì)象terminal_heartbeat_dict和一個(gè)成員變量heartbeat_lock:
Self.terminal_heartbeat_dict = {}
Self.heartbeat_lock = threading.Lock()
Python中的字典對(duì)象是一種類似于哈希表的映射類型對(duì)象,是一種可變的容器類型,由多個(gè)鍵值對(duì)(key,value)組成。用Threading.Lock()生成一個(gè)線程互斥鎖[5-7]。當(dāng)有設(shè)備發(fā)來(lái)請(qǐng)求時(shí),經(jīng)URLConf調(diào)配后,調(diào)用TerminalManager類的heartbeat方法,該方法接受一個(gè)terminalid(終端編號(hào))參數(shù),每調(diào)用一次便將終端編號(hào)和當(dāng)前時(shí)間作為一個(gè)字典的item存到terminal_heartbear_dict中:
With self.heartbeat_lock:
Self.terminal_heartbeat_dict[terminalid] = now_datetime
在Python中,With語(yǔ)句可以在執(zhí)行時(shí)自動(dòng)進(jìn)入和退出With后所跟的上下文管理器對(duì)象,常用于對(duì)文件的操作和鎖機(jī)制等。當(dāng)系統(tǒng)接收到一次請(qǐng)求時(shí)便對(duì)線程加鎖,避免同一時(shí)刻對(duì)共享資源進(jìn)行操作引起沖突,更新字典中的值,操作完成后釋放鎖。
2.2 節(jié)目推送實(shí)現(xiàn)
媒體發(fā)布系統(tǒng)中所有設(shè)備的媒體播放都依賴于系統(tǒng)調(diào)度,系統(tǒng)調(diào)度需要精確到某個(gè)商店的某臺(tái)設(shè)備,從而實(shí)現(xiàn)精準(zhǔn)推送。因此,節(jié)目推送也是系統(tǒng)中至關(guān)重要的一環(huán)。
基于媒體播放系統(tǒng)的實(shí)際需求,客戶、商店、設(shè)備之間都是多對(duì)一的關(guān)系,節(jié)目推送是在視頻的基礎(chǔ)上生成節(jié)目單后再推送,因此視頻與節(jié)目單為多對(duì)多的關(guān)系,如圖5所示。按照需求,節(jié)目單和客戶、商店、設(shè)備之間又是多對(duì)多的關(guān)系,數(shù)據(jù)之間的關(guān)系十分復(fù)雜,若自己編寫數(shù)據(jù)關(guān)系,不僅難以實(shí)現(xiàn),而且容易耦合,更不易于系統(tǒng)的升級(jí)與維護(hù)。
在Django中,使用ORM技術(shù)來(lái)操作數(shù)據(jù)庫(kù),開發(fā)者通過(guò)編寫Python類的方式實(shí)現(xiàn)數(shù)據(jù)模型,該數(shù)據(jù)模型以框架底層作為支撐,映射到數(shù)據(jù)庫(kù)中的每張表,類中的屬性則對(duì)應(yīng)表中的每個(gè)字段[8]。此外,Django還提供了三種最常見的數(shù)據(jù)庫(kù)關(guān)系,即多對(duì)多(many-to-many),多對(duì)一(many-to-one),一對(duì)一(one-to-one)。直接操作框架中提供的基于Python類的管理器即可實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的增、刪、改、查操作。
以節(jié)目推送到設(shè)備為例,節(jié)目單和設(shè)備是多對(duì)多的關(guān)系。推送時(shí),將節(jié)目單的數(shù)據(jù)庫(kù)主鍵id(itemid)和設(shè)備的數(shù)據(jù)庫(kù)主鍵id(terminal_id)傳到后臺(tái),Django通過(guò)id獲取類的實(shí)例,即數(shù)據(jù)庫(kù)中的一條數(shù)據(jù):
item = Item.objects.get(id=itemid)
terminal = Terminal.objects.get(id=terminal_id)
其中,objects是Django內(nèi)部封裝的類管理器,通過(guò)該管理器可以操作類實(shí)現(xiàn)數(shù)據(jù)庫(kù)層面的增、刪、改、查、操作,Django模型操作接口見表1所列。
后臺(tái)獲取到節(jié)目單和終端實(shí)例后,調(diào)用Django的反向查詢方法獲取該終端下已存在的所有節(jié)目單:
Terminalist = terminal.item_set.all()
若節(jié)目單item已存在Terminallist中,則忽略;否則調(diào)用Django的多對(duì)多反向增加方法在數(shù)據(jù)庫(kù)中生成第三張表,分別存儲(chǔ)節(jié)目單id和終端id,見表2所列。
推送完成之后,該終端向服務(wù)器發(fā)送請(qǐng)求,按照事先約定的協(xié)議返回該終端名下所有的視頻信息:
{"items":[{"videos":[...],"itemid":"itemid",}],"userid":"terminal_id","respound":"登錄成功"}
設(shè)備按照解析的數(shù)據(jù)[9],經(jīng)由服務(wù)器訪問(wèn)靜態(tài)數(shù)據(jù),即可實(shí)現(xiàn)定點(diǎn)推送,定點(diǎn)播放。
3 系統(tǒng)部署與應(yīng)用
在實(shí)際生產(chǎn)環(huán)境的部署過(guò)程中,采用Nginx反向代理uWSGI方式,靜態(tài)文件由Nginx處理,具體的動(dòng)態(tài)業(yè)務(wù)邏輯由uWSGI的Django處理。系統(tǒng)的部署結(jié)構(gòu)如圖6所示。
系統(tǒng)運(yùn)行時(shí),前端請(qǐng)求發(fā)送到反向代理服務(wù)器Nginx,如果請(qǐng)求的是靜態(tài)文件,則Nginx服務(wù)器直接訪問(wèn)服務(wù)器磁盤[10,11];如果是動(dòng)態(tài)數(shù)據(jù),則把請(qǐng)求代理到Web服務(wù)器uWSGI,uWSGI服務(wù)器調(diào)用Django應(yīng)用,經(jīng)過(guò)Django中一系列邏輯處理后與MySQL交互數(shù)據(jù),然后將處理結(jié)果返回給前端展示,實(shí)現(xiàn)Web請(qǐng)求。
4 結(jié) 語(yǔ)
本文基于Python的Django框架設(shè)計(jì)實(shí)現(xiàn)了一種多媒體發(fā)布系統(tǒng),與現(xiàn)有的媒體發(fā)布方式相比,本系統(tǒng)不僅實(shí)現(xiàn)了對(duì)所有終端設(shè)備的實(shí)時(shí)監(jiān)控和精確定位,同時(shí)還能夠?qū)崿F(xiàn)對(duì)單個(gè)設(shè)備播放內(nèi)容的精確實(shí)時(shí)推送。除此之外,采用的Django框架開發(fā),方便后續(xù)對(duì)系統(tǒng)的自動(dòng)化維護(hù)和升級(jí)。
目前該系統(tǒng)上線運(yùn)行以來(lái),已經(jīng)在北京、上海、杭州、南京等城市部署安裝了一萬(wàn)余臺(tái),充分證明了該系統(tǒng)媒體發(fā)布的高效性和穩(wěn)定性。
參考文獻(xiàn)
[1]張秋,魏成光.多媒體信息發(fā)布系統(tǒng)在大學(xué)圖書館的設(shè)計(jì)與應(yīng)用——以清華大學(xué)人文社科圖書館為例[J].圖書館學(xué)研究,2011(20):38-41.
[2]陳艷,葉德建.營(yíng)銷類多媒體信息發(fā)布系統(tǒng)終端自動(dòng)化運(yùn)維[J].微型電腦應(yīng)用,2016,32(1):25-29.
[3]白文秀,吳瑞苗.基于Django的運(yùn)維自動(dòng)化系統(tǒng)設(shè)計(jì)[J].智能計(jì)算機(jī)與應(yīng)用,2016,6(3):95-97.
[4]楊澤,鄭立華,李民贊,等.基于Django的植保無(wú)人機(jī)飛行監(jiān)視系統(tǒng)[J].農(nóng)業(yè)網(wǎng)絡(luò)信息,2016(9):41-47.
[5]陳忠菊.一種基于多線程的高并發(fā)任務(wù)實(shí)現(xiàn)[J].電腦編程技巧與維護(hù),2015(5):41.
[6]肖明魁.Python語(yǔ)言多進(jìn)程與多線程設(shè)計(jì)探究[J].計(jì)算機(jī)光盤軟件與應(yīng)用,2014(15):66-67.
[7]謝紅.Python多線程機(jī)制初探[J].電腦知識(shí)與技術(shù),2011,7(19):4739-4740.
[8]陳紅茜,孟超英,邱小彬,等.基于Django的高校合同制人員管理系統(tǒng)[J].華東師范大學(xué)學(xué)報(bào)(自然科學(xué)版),2015(S1):464-470.
[9]范文星.基于Django的網(wǎng)絡(luò)運(yùn)維管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)科學(xué),2012,39(S2):175-177.
[10]馮貴蘭,李正楠.Nginx反向代理在高校網(wǎng)站系統(tǒng)中的應(yīng)用研究[J].網(wǎng)絡(luò)安全技術(shù)與應(yīng)用,2017(6):111-120.
[11]汪文君.基于Nginx服務(wù)器集群負(fù)載均衡方案的研究和改進(jìn)[J].電子世界,2017(2):179-181.endprint