蔣洪磊
(中國電子科技集團公司第五十四研究所,河北石家莊050081)
基于Python的網管軟件技術體系設計
蔣洪磊
(中國電子科技集團公司第五十四研究所,河北石家莊050081)
針對C/C++在網管開發中效率低下、維護和調試成本高的問題,提出采用動態語言Python所組成的輕量級開發架構。在介紹Python的動態類型系統及其元編程能力的基礎上,給出在B/S架構的網管軟件中設備監控、Web開發、ORM等技術選擇:利用Python的數據結構來對二進制流格式進行描述,程序可以自動地在二進制流和JSON結構間進行雙向轉換?;贔lask的微Web框架,簡單易用擴展,有著豐富的插件,支持服務器推送事件。SQLAlchemy作為Python中對象關系建模的事實標準,使得開發人員從各種數據庫的差異中解脫出來。項目實踐表明基于Python的實現代碼簡潔,可讀性更強,具有快速開發優勢。
Python;動態類型;元編程;設備監控;Web服務器架構;對象關系映射
一二十年前的網管開發,通常采用C/C++的技術體系;然而隨著硬件性能的提高,其所帶來的運行性能優勢越來越不明顯,而其高昂的學習成本,低下的開發效率,開發人員的參差不齊,以及由此帶來的代碼健壯性、代碼維護成本等問題,以及對Web開發支持的缺乏等等,使其越來越難以適應現代網管的開發工作。為此,提出基于Python的輕量級軟件開發架構。
Python[1,2]是一門面向對象的動態語言[3,4],它適用于文本處理、圖形處理、科學計算[5-7]、Web網站、設備監控[8]的快速開發。在編譯時獲得類型的稱為靜態類型系統,其優勢是可以在執行前發現類型不匹配錯誤,并能根據類型信息進行編譯時優化以提高執行速度;而動態類型系統則是在運行時才能知道變量的類型,因而在編寫代碼時無需聲明變量的類型。代碼中缺少類型聲明,降低了程序的執行效率,卻使得代碼變得更加簡潔,開發人員不再關注于數據類型聲明這些非本質的部分,而專注于處理業務邏輯。
動態語言還具有在程序執行時獲取、改變程序信息的能力。在不同的語言中稱為反射(reflection)、自省(introspection)或者元編程(meta-programming)。Python可以在運行時獲取對象的類型信息(內置函數type/isinstance/issubclass)、查詢對象當前擁有的屬性和方法(內置函數dir/hasattr/getattr)、增刪對象的屬性/方法(內置方法del)、在運行時將字符串編譯為程序并成為程序的一部分(內置函數eval)等等。這一能力,使得開發人員可以在運行時環境中進行即時開發。在靜態語言開發中,雖然可以設置斷點,查看或者修改變量的數值,但是新編寫的代碼只能在保存文件、整個項目重新編譯再重新運行后才能得到驗證。而在動態語言中,則可以在斷點處的上下文中立即執行來驗證代碼的正確性,如果正確則保存新編寫的代碼,如果代碼編寫錯誤則修改后再次立即執行。例如在Python的集成開發環境WingIDE中,可以使用Debug Probe窗口進行運行時開發。元編程不僅可以簡化設計模式的實現,提高開發人員對程序的操控能力,還可以在不改變已有代碼的情況下而對功能進行追加和變更,這在開發中稱為猴子補?。╩onkey patch)。開發人員可以利用這種靈活性來修訂正在運行中的程序錯誤[9]。
由于動態語言所具有的豐富表現力,使得動態語言的代碼實現更加簡潔,維護和排錯成本更低[10]。根據各種實際項目的對比,動態語言的代碼量只有相同靜態類型代碼的1/3到1/5,而開發效率是靜態語言的3~5倍。例如應用C++進行國產達夢數據庫開發時,需要的代碼量是近兩萬行代碼,需時數月;而遷移到Python后,利用自主開發的SQLAlchemy方言,則只需不足千行代碼,用時不到1周。由于動態類型使得在執行時才能發現錯誤、閱讀程序時可用到的線索較少,因此相比靜態語言開發人員,動態語言的開發者更依賴于運行時測試用例和良好的文檔編寫習慣。
在衛星通訊系統的綜合網管中(如圖1所示),需要完成該衛星通訊系統的綜合業務管理、網絡運行狀態監視,設備監控等各種功能。用戶的操作內容在進行相應的業務邏輯處理后,以JSON格式,由DevMonitor根據對應的設備協議進行轉換,由相應的SatSide或者EarthSide模塊發送。Web客戶端以AJAX向Web Framework發送請求并注冊Server Send Event(服務器推送事件,簡稱SSE),當設備狀態發生變化時,則沿反向路徑,由DevMonitor轉換為JSON格式后經Web框架推送給瀏覽器。

圖1 衛星網管系統的基本架構
2.1 設備監控
為了獲取網絡運行狀態,必須對網絡中的設備進行監控[11]。利用Python的pySerial、pyParallel、pyUSB、PyVISA等庫可以與設備的串口、并口、USB等接口進行通信。在數據包的封裝格式上,底層設備通常采用自定義的二進制流封裝格式[12,13],而Web開發中則通常使用JSON包作為Web客戶端與服務器交互的協議格式。在協議解析部分,利用Python的語言特性,用協議格式描述來替代手工為每種格式的包進行編碼解析。如下所示,pack_des_ list的協議格式描述了表1和表2所示的包格式:

可以看出只需要不到10行代碼就可以將這種包格式描述完成。通過將該協議描述作為參數輸入通用的解包函數depack_buffer,就可以完成自定義二進制流格式到JSON格式的轉換,或者使用封包函數pack_buffer完成逆向操作。在實現新的協議格式時,只要編寫協議的格式描述,就能將數據包自動解析為相應的數據結構,而不需要額外編寫一行代碼。

表1 站控信息幀結構

表2 設備控制響應數據字段格式
對于每一個pack_des_list的項,第一個字段表示該項(或者稱為字段)的長度或者數目,第二個字段表示該項的名稱,如果為None表示該字段保留,解包程序將直接跳過。第三個字段的類型可以是dict,tuple或者list,這3種類型都是Python的基本數據類型。我們用dict(字典)來描述給定項的處理方式,如”type”:str表示該字段的類型為字符串,缺省類型為整形數;”tmp”:True表示該項是臨時項,在后繼處理完畢后不會反應到最終結果中,缺省為非臨時項。如果第三字段的類型為list(列表),則表示后面按可變長的數組解析,其長度為該項的值。如果第三字段的類型為tuple(元組),則后面為固定長數組,其長度為該項第一字段的值。list或者tuple可以進行任意層次嵌套,如“DevNum”項下面又嵌套著”ArgNum”,表示該數據包可以一次返回多個設備的,每個設備多個參數的設置狀態。
可以看出,讓開發人員編寫協議描述比每次單獨為每種包格式編寫封包和解包代碼要高效的多,而且不容易出錯。此外,由于協議描述本身就是Python的數據結構,這使得用戶編寫的代碼可以直接利用IDE的語法檢查工具來判斷是否出錯。此外,該協議描述能夠容易描述現有的協議格式,從而快速實現已有協議的解析。
2.2 Web服務器
Python的Web Framework有很多種,選擇的是Flask,其優勢是簡單且易于擴展,有豐富的插件來實現認證、鑒權、會話管理、Cache、存儲、文件上傳、ORM等各種功能。URL路由使得用戶可以使用自由彈性的網址,Flask根據約定優于配置的設計原則,約定所有靜態文件,均放在/static/目錄下;而所有模板文件,均放入/template/目錄下。
直接使用URL路由等于將URL地址和實現代碼進行了綁定,這在簡化開發的同時也造成了兩者的緊耦合。在進行大型項目開發時,為實現模塊化并行開發,可以使用Flask的Blueprint(藍圖)技術,將一個應用劃分為若干Blueprint集合,然后將一個Blueprint注冊到一個應用的URL前綴或子域名之下。可以將一個blueprint以多個不同URL rules在同一個應用中注冊多次。在Blueprint中提供模板filters、靜態文件、模板等utilities。Blueprint除了方便模塊化開發,還完成了URL組織與功能實現的解耦合。
2.3 對象關系映射
ORM將數據庫的Table映射為類,Column映射為類的屬性,Table中的每條Record則映射為一個類的對象。ORM通過更高層次的抽象,屏蔽數據庫間的差異,并代替用戶處理連接、緩存、一致性管理等細節,從而提高了開發效率。由于用戶不再直接使用SQL代碼,不易產生SQL注入攻擊,也提高了安全性。
Python中的SQLAlchemy可以完成Object Relational Mapping(ORM)的功能,以實現通過面向對象語法來操控數據庫,將商業邏輯與數據庫操作邏輯分開。如圖2所示,在SQLAlchemy中Dialect負責將通用的操作命令轉換為各種數據庫的方言,從而對上層用戶操作屏蔽數據庫間的差異;Connection Pooling(連接池)用于保持和維護和DB的連接,這樣不用每次操作都建立和斷開連接,從而提高IO性能。DBAPI則是用于連接數據庫的API接口。而連接Oracle數據庫需要安裝對應版本的Oracle instantclient和cx_Oracle庫。通過使用SQLAlchemy,用戶的實現代碼不在依賴于具體的數據庫,只需要少量代碼就可以完成從一種數據庫到另一種數據庫的遷移。此外,基于SQLAlchemy的Alembic庫可以方便進行數據庫的遷移及版本控制。

圖2 SQLAlchemy的組織結構
2.4 服務器推送事件
Server Send Events(SSE)是實現服務器主動推送消息的最簡單方式,可以結合RESTful技術實現協同編輯或者實時反應設備的狀態。在用Python 的Flask來實現SSE非常簡單,只需要將之前通過設備監控解析出得結構體直接創建為JSON包放入相應的事件隊列??蛻舳俗許SE所需的服務器端處理函數需要對每類事件(event_name)的每個訂閱者(uuid)創建一個Queue,只要Queue中有事件,則推送給該訂閱者。SSE的服務器端處理函數定義如下:


介紹Python語言的動態特性,給出了實現B/S架構的網管體系中所需要的設備監控、Web服務開發、ORM的技術方案。從本文可以看出,通過采用Python的輕量級開發架構,可以極大地提高開發人員的工作效率,用更少的代碼完成相同的功能,使用戶關注于業務的實現而非技術細節,從而使軟件的功能更加契合用戶需求,并能夠進行快速的響應需求變更。
[1]Mark Lutz.Learning Python(Fifth Edition)[M].Sebastopol US:O’Reilly Media,Inc.,2013.
[2]Mark Summerfield.Programming in Python 3 Second Edition[M].Boston US:Pearson Education,2010.
[3]松本行弘.松本行弘的程序世界[M].北京:人民郵電出版社,2011.
[4]Paul King.動態語言的敏捷開發實踐[C]∥QCon2010.北京,2010.
[5]Sandro Tosi.Matplotlib for Python Developers[M].Birmingham UK:Packt Publishing,2009.
[6]HYRY Studio.用Python做科學計算[M].北京:清華大學出版社,2012.
[7]Hans Petter Langtangen.A Primer on Scientific Programming with Python 2rd[M].US:Springer,2015.
[8]Hughes JM.Real World Instrumentation with Python [M].Sebastopol US:O’Reilly Media,Inc,2011.
[9]王浩波,郭金鵬.星載環境下可重構技術分析[J].無線電工程,2012,42(1):40-42.
[10]孔慶玲,胡志軍,劉英,等.程序復雜性度量技術分析[J].無線電工程,2011,41(2):61-64,2011.
[11]劉學輝,王國良.軟件進程監控系統及其實現[J].無線電工程,2011,41(9):62-64.
[12]許靜.高效信息收發軟件系統設計分析[J].無線電工程,2011,41(9):7-10,43.
[12]王明,何加銘,曾興斌.IP攝像頭遠程監控系統的設計與實現[J].無線電通信技術,2014,40(1):71-74.
Design on Python-based Network M anagement Software Architecture
JIANG Hong-lei
(The 54th Research Institute of CETC,Shijiazhuang Hebei050081,China)
In view of such problems as low efficiency in developmentand high cost inmaintenance for networkmanagement system with C/C++languages,this paper proposes a lightweight architecture based on dynamic language Python.On the basis of Python’s dynamic-type system and meta-programming capability,this paper presents such technical selections in networkmanagement software of browser/server(B/S)architecture as devicemonitoring,web development,ORM,etc.The Python’s data structure is used to describe binary stream protocol,and the bidirectional exchange of program can be automatically performed between binary packet and JSON.The micro web framework Flask is easy to use and extend,supports Server Send Event.SQLAlchemy,as a de facto standard for ORM in Python,makes developers handle database like objects.The project practice shows that Python-based implementation is simple,more readable and has higher development speed.
Python;dynamic types;meta programming;devicemonitoring;web server framework;ORM
TP393
A
1003-3114(2015)04-87-4
10.3969/j.issn.1003-3114.2015.04.23
蔣洪磊.基于Python的網管軟件技術體系設計[J].無線電通信技術,2015,41(4):87-90.
2015-04-09
國家部委基金資助項目
蔣洪磊(1982—),男,博士,工程師,主要研究方向:分布式存儲、衛星通訊網網管運控。