韓 超
(衢州市氣象局, 浙江 衢州 324000)
淺談在線內容管理系統的業務化改造
韓 超
(衢州市氣象局, 浙江 衢州 324000)
結合氣象部門的業務環境特點,通過對在線內容管理系統內部URL機制的分析、數據模型的拓展以及功能模塊的改造構建一個基于Web Service技術的數據交互平臺。讓運行在移動平臺、桌面系統平臺和網頁平臺的氣象業務系統能夠跨平臺、跨語言并且無需任何第三方附加得進行數據交互,讓分布于不同節點以及不同類型的數據庫在這個交互系統中能夠協同調用。讓這個交互系統能夠基于網絡進行針對性的優化開發。
業務平臺;數據交互;CMS;Web Service
在線數據的交互機制對于一些基于網絡服務的氣象業務來說,起著至關重要的作用。尤其是近年來移動互聯技術的迅猛發展,伴隨著移動智能終端數量的急劇增加,給網絡內容推送的流暢性和穩定性帶來了空前的壓力。一個沒有緩存機制和交互邏輯的網絡內容管理系統,不僅會大幅增加我們的硬件維護成本,更讓我們的網絡服務平臺在面對大量數據請求時陷入癱瘓。目前一些基于PHP語言開發的內容管理系統,雖然在工作邏輯和認證方法上有著較為成熟的解決方案,但卻無法滿足氣象部門復雜數據環境的要求。因而了解這些內容管理系統的工作機制,并結合氣象部門自身的網絡環境特點加以改造,將對氣象網絡平臺的服務體驗有著極其重要的意義。
內容管理系統也叫“Content Management System”,一般簡稱為CMS系統。是一種介于Web服務器和辦公流程之間的軟件系統。它重點解決了各種非結構化或半結構化數字資源的采集、管理、利用、傳遞和增值,并能有機集成到結構化數據的商業智能環境中。隨著網絡服務復雜度和功能性需求的不斷增長,如今以內容管理為應用核心的CMS產品大有百花爭艷的感覺。這些CMS大致上基于兩套框架編寫:PHP+MySQL和.NET+MSSQL。前者相比后者更具開放性和便攜性,能運行于UNIX、LINUX、WINDOWS下,且PHP和MySQL兼具開源免費的特點,使得基于PHP+MySQL的CMS在市場采用率和系統成熟度上要優于.Net+MSSQL的CMS。
近年來我國氣象事業的不斷發展使氣象業務發生了根本性的變化。如今的氣象部門以高分辨率、多方位連續監測的觀測方式為主。這決定了氣象資料采集的高密度和龐大的數據量,并形成了資料存儲以結構化數據庫為主非結構化數據資料并重的現狀。Access、MsSQL、Oracle等多種數據庫在不同的氣象業務領域都發揮著不同的作用。氣象服務也從傳統的天氣預報領域向環境領域不斷拓展,伴隨而來的則是服務平臺、服務內容和受眾群體的持續增長。氣象部門在新形勢下的諸多特點要求一個合格的內容管理系統因當具備以下3點特質:首先,系統不能局限于單一的數據庫類型,要具備將不同的數據表內容分散到不同數據庫中的功能。優化系統實現負載均衡的同時,還連接了分散在不同氣象領域的各個數據庫。其次,內容管理系統對于氣象資料的推送不能局限于純靜態或動態生成的方式,應當能夠響應不同軟件平臺的要求分類推送不同性質的內容。擁有這種靈活的內容緩存機制,才能通過網絡流暢穩定得將氣象數據推送到性質不同的終端上去。第三,系統還應該擁有Web Service技術的一些特質,支持跨語言跨系統平臺之間的數據交互。綜合考慮這些特質,決定采用對二次開發比較友好的Phpcms系統作為業務化改造的基礎系統,借由這個系統的數據交互邏輯并在數據模型的支持上加以改造。
Phpcms是一個基于MVC框架模式設計的CMS系統。它采用單一的入口文件,并且系統中的數據邏輯、數據顯示和用戶交互的處理部分都相互獨立。這種低耦合的構建方式使得系統本身的視圖層和業務層分離,讓我們能以最小的代價對系統業務邏輯進行拓展和改造。
系統啟動從入口文件index.php開始,在這里加載并初始化了位于phpcms目錄下的框架入口文件base.php,在base.php里完成了一系列的系統變量及模型文件加載機制定義,最后進入phpcm/lisbs/classes目錄下的應用程序創建類application.class.php,實例化application之后系統實現了MVC框架里最重要的控制器功能并進入了真正的程序邏輯部分:至此系統初始化工作基本完成,其邏輯流程如圖1所示。

圖1 系統初始化流程
2.1 URL路由機制
PHPCMS的控制器指向是由URL路由機制實現的,它是整個系統最關鍵的部分。這種路由機制是URL鏈接和系統模塊之間的橋梁,負責將進入瀏覽器的請求映射到系統的各個控制器,以此讓系統作出不同的邏輯處理。它從系統入口文件index.php開始,附加3個名為“m”、“c”、“a”的固定url參數,用來表示請求執行模型“M”下名為“C”的控制器中名為“A”的方法。系統內部的各個模型統一存放在modules文件夾下,所以一個形如index.php?m=content&c=index&a=show&catid=9&id=1鏈接的具體實現為, Url傳入后在application類的實例中對各個參數進行拆解分類,篩選出“M”、“C”和“A”3個變量為系統固定參數其余變量為函數參數,然后通過在base.php中定義的方法,在系統固定路徑下以變量“M”為文件名的模型文件夾中,找到以變量“C”為文件名的控制器文件,并最后在此文件中執行以變量“A”為方法名的函數。所以這個鏈接的具體含義為執行系統路徑下modules/content/index.php文件中的index->show方法,并且執行的同時給show方法傳入catid=9和id=1兩個參數。
這種簡便有效的控制器載入機制不僅局限于在網頁瀏覽器上展示網站內容,它更支持通過HTTP協議的post和get方法與遠程服務器進行交互,以此可以在氣象業務網絡環境中建立一系列跨平臺跨語言的數據交互接口。例如一個氣象數據查詢平臺,它的界面展示部分由delphi或C#語言開發,它的數據查詢和數據邏輯部分基于CMS系統開發并通過Url的形式獲取。此時CMS系統不僅可以方便得對所有桌面程序的請求內容和請求頻率進行統計,還可以基于統計的結果進行優化并以緩存的形式推送,即是將請求頻率較高的查詢內容以xml、xsd、json文件的形式事先打包緩存在服務器。此外這個氣象數據查詢平臺的服務端URL請求鏈接可以用API文檔的形式組織起來并在氣象內網上共享,其它業務開發或者平臺自身向ios、android系統拓展時都能作為一種寶貴資源被再次利用。
3.1 工廠模式
氣象部門基于數據庫所開發的業務平臺有很多,但能用多態性的編程理念,做到各類數據庫統一調用管理的平臺卻并不多見。PHPCMS系統雖然用工廠模式實現了這個機制,但系統本身的數據庫擴展只停留在了MySql這一個類型上。所以理解CMS系統數據庫的多態性擴展方式,并針對氣象部門擁有的數據庫類型進行擴展,成了業務改造工作中的重點。
PHPCMS數據庫操作的工廠模式通俗來說就是用一個能夠創建多種數據庫實例的提供者類,根據配置設置或者程序邏輯來決定實例化哪一種數據庫。所以在PHPCMS系統內部主要由以下4種類來實現數據庫的多態性機制:1)能夠根據配置提供不同數據庫實例的工廠類。以db_factory.class.php命名,位于phpcms/libs/classes/目錄下;2)負責告訴工廠類應該實例化哪種數據庫的配置類。以database.php命名,位于caches/configs/目錄下;3)用來被工廠類實例化并且負責實現數據庫具體操作的產品類。這種類文件的命名以數據庫名稱開頭,后面附加.class.php,形如mssql.class.php,位于phpcms/libs/classes/目錄下;4)根據工廠類可能提供的不同數據庫實例,實現不同數據庫實例同一化操作的模型類,為向后基于功能模塊的擴展提供基類。以model.class.php命名,位于phpcms/libs/classes/目錄下。以上4種文件共同構成了系統數據庫操作的基石,其功能布局和業務邏輯如圖2所示。

圖2 數據庫多態性擴展的實現邏輯
3.2 數據庫操作模型的拓展
系統數據操作方面的改造工作首先應當從底層驅動的擴展開始。PHP作為開源免費的項目多年來一直受到各大IT廠商的青睞,所以PHP對各類數據庫都有很不錯的驅動支持。在PHP官方主頁https://pecl.php.net的Database專欄下提供了55種功能各異特性不同的數據庫驅動,包括在氣象業務工作中可能用到的Mssql、Oracle、Mysql、Sqlite甚至是DB2和Lotus Notes的驅動。對同一種數據庫的驅動選擇上,盡管以PDO為代表的驅動能在不同數據庫之間提供統一的API接口,但非統一接口的驅動在運行效率、功能性和版本兼容性上都要優于PDO驅動。在獲得所需的驅動文件后,手動修改PHP的配置文件php.ini,加載相應驅動文件即可實現對數據庫驅動的拓展支持。在服務平臺有了對各類數據庫的基本支持后,相應代碼的編寫工作可以從工廠模式下的四種類庫著手,重點是新建mysql.class.php為代表的產品類,小幅修改db_factory.class.php工廠類和model.class.php模型基類。
首先是產品類的拓展。一系列的產品類不僅關系到各種數據庫的直接操作,在系統內部更負責向工廠類提供一致的實例化接口,向模型類model.class.php提供一致的數據庫操作方法,所以在代碼組織上要求各種產品類的方法函數要有一致的名稱,以及產品類之間的功能交集要大于等于模型類中調用到的方法函數,只有這樣才能保證后面的模型類在拿到工廠類提供的數據庫實例后,能用統一的函數名實現功能一致的方法。所以在函數方法名稱上必須以mysql.class.php類為參照標準,用“open”、“close”作為開啟和關閉數據庫連接資源的名稱標識以備db_factory.class.php在實例化時調用,并以“select、get_one、query、insert、update、delete、count、affected_rows、get_primary、get_fields、table_exists、field_exists”為數據查詢的功能布局。在整個產品類的功能交集中,除了“select”方法所涉及到的分表查詢在不同數據庫中略有區別外,其它功能方法都能在各自的驅動接口API上找到。在mysql數據庫中分表查詢可以通過“limit”語句輕松實現,而在mssql和oracle中則需分別通過“ROW_NUMBER”和“RANK”來實現。在Oracle中需通過如圖3所示方式實現。

圖3 Oracle實現Limit分頁查詢的方法
在mssql中需通過圖4所示方式實現。

圖4 Mssql實現Limit分頁查詢的方法
產品類編寫完畢后,需要對PHPCMS系統原有的工廠類文件db_factory.class.php做小幅的改動,以適應新增數據庫類型的實例化工作。db_factory.class.php類是基于單件模式設計的,類成員函數“get_database”通過接收一個代表數據庫類型的字符串參數,來決定向外界傳遞何種類型的數據庫實例。
而這種類型初始化的選擇機制是通過一個switch-case語言來實現的。所以想要拓展工廠類所能支持的數據庫類型,只需在類函數“connect“內的switch語句中,新增case選擇條件即可。例如“case′ mssql′:
pc_base::load_sys_class('mssql','',0);$object=new mssql();break;”這樣簡單的幾行語句即可完成一類數據庫的擴展工作。
在完成db_factory.class.php工廠類的改造工作后,再配合原系統的model.class.php模型基類,可以說基本已經完成了數據庫平臺支持的拓展工作。但鑒于部分數據庫對于數據庫表名稱大小寫的特殊要求,還需要模型基類在讀取數據庫參數設置時做一些針對性的處理。例如在模型基類的構造函數里添加“if($this->db_config[$this->db_setting]['type']=='oracle');$this->table_name=strtoupper($this->table_name);”,用來將database.php里的數據庫表名統一成大寫字母。
在系統數據操作類庫拓展完畢之后,可基于這種多態性的數據模型結構,并結合氣象業務的特點進一步開展氣象業務模塊的開發工作。由于phpcms系統是基于MVC框架構建的,受益于這種高內聚、低耦合的代碼組織方式,我們的模塊開發工作可清晰的分為兩個部分:1)數據庫操作模型的拓展,在系統路徑“phpcms/mode/”下派生模型基類model.class.php,并且在database.php中完成相關參數配置;2)功能模塊的開發,在系統路徑“phpcms/modules/”下新建以模塊名稱命名的文件夾,并在此文件中完成數據交互邏輯相關類庫的開發。
4.1 數據庫操作模型的拓展
拓展工作主要涉及database.php和model.class.php這兩個類文件。database.php并不是一個類文件,它僅作為一個代碼片段存在于phpcms系統的配置文件夾下,主要功能是向包含它的類庫文件返回一個數據庫配置信息列表以供變量成員挑選并賦值。database.php的代碼結構由一個二維數組構成,數據庫的連接參數以庫為單位存儲在這個數組里。數組的第一個維度是配置參數的自定義名稱,第二個維度則是這個名稱所對應的具體參數。所以在database.php中新增數據庫參數配置,只需在文件返回的二維數組中新增一條形如“test=>array(…數據庫參數…)”的記錄即可。其次是在model.class.php類的基礎上派生新的數據模型。這個數據模型是基于表設計并且能被高度重用的。它僅表示數據庫操作層面的一種模型并不確切指向前臺的某種交互邏輯。數據模型與功能模塊之間的低耦合性,使得一個模塊功能的數據操作可以由多個指向不同類型數據庫的模型共同組成。model.class.php類的派生編寫工作也很簡單,新的子類只需要在重載構造函數時重新定義參數配置名和數據表名即可。
4.2 模塊的開發
系統模塊的根目錄位于“phpcms/modules/”路徑下,目錄中是以具體功能為分類命名的各個模塊文件夾,文件夾內包含的類文件則是各類數據交互的執行邏輯。在類文件的執行方法中,以“$this->db = pc_base::load_model('xsweb_168_nowcasting');”的形式,在加載相應數據模型的同時即可完成數據模型的初始化工作,然后根據model.class.php類中提供的方法函數,便可完成數據庫的交互操作。只要熟知系統的URL機制和模塊加載機制,模塊類可按需推送圖片鏈接、二進制文件鏈接或者直接推送明文或二進制文件等各類數據格式。
模塊的開發工作可充分利用網絡語言的特點進行深度優化。僅以推送不同時間跨度的降水量統計數據為例:1)可在推送數據的同時,模塊向系統自身提交一條url鏈接以統計請求的頻率和數量。如此可在不影響數據推送的同時完成統計工作;2)基于這種統計,當某時間跨度的雨量請求數量達一定量級時,系統在更新請求數值的同時,在特定目錄生成一個以時間戳和特定ID命名的內容為空的標識文件,并以此文件為信號決定是否在響應請求時生成json或xml等格式的靜態文件緩存在服務器,在第二次響應相同的請求時將靜態文件的內容直接發送給客戶端;3)系統平臺可以是分布式存在于多個節點之中的。用一臺服務器作為響應請求的入口,以請求客戶端的地理分布為條件向其它服務器分別發送請求信息并最終獲取請求結果反饋給客戶端;4)可將特定內容提前生成緩存文件,在響應請求時不經過數據庫和其它執行邏輯直接發送給客戶端。
“歷史上的今天”是衢州氣象內網頁面中的一個數據展示模塊,欄目內容包含“歷史上的今天”、“歷史上的明天”、“歷史上的未來三天”和“歷史上的未來十天”4個方面,欄目數據涉及衢州各縣市建站以來各項溫度數據,降水數據以及降水頻率的分類統計。由于網站本身通過對phpcms改造而構建出一個Web Service平臺,所以給欄目本身的多平臺拓展和優化帶來了巨大的改變。
5.1 多平臺的拓展
從欄目內容上看,這類歷史均值、極值統計模塊的應用范圍比較廣泛,在各類氣象網站、手機APP終端或桌面業務平臺中都非常常見。然而對于開發者來說,要在特性和編程語言都不盡相同的各個平臺中開發功能相近的項目,意味著大量重復且無法避免的數據庫編程工作。但基于web service平臺開發后,欄目在安卓平臺上推出時可由欄目現成的Url獲取數據并直接介入界面UI的開發,其開發流程如圖5所示。

圖5 基于WebService技術的系統多平臺開發流程
5.2 優化和效益評估
項目的跨平臺工作通常會帶來兩個不可避免的問題。首先是支撐服務器維護的工作量會成倍增加。其次,隨著平臺數量的增加和客戶端系統的差異化加劇,系統的整體穩定性會受到嚴峻的考驗,并導致系統優化的難度不斷加大。然而通過改造Phpcms系統構建一套基于web service技術的數據推送平臺,能夠將這些難題化零為整,統一優化一勞永逸。
在“歷史上的今天”這個欄目中,為了提高欄目本身的穩定性和應對大量客戶端并發請求的負載性能。
我設計了這樣一個簡單而有效的php進程協同模式:應對短時間內大量的并發請求時,數百個各自獨立的php處理進程并不會搶著向數據庫服務器要統計數據,眾多進程間會等待第一個向服務器發出請求的進程,直至該進程拿到統計數據并形成緩存文件,其他進程再獲取這個緩存文件內的統計結果。
為檢驗欄目在如此改造后的工作效率,特別設計了這樣一個對比實驗:實驗通過并發線程的方式模擬數百個客戶端在500 ms的時間內隨機向服務器請求欄目所需的統計數據,隨著并發客戶端數量的增加記錄每個客戶端完成統計需要的毫秒數并取平均值。實驗的前提:1)實驗的客戶端都是通過j2se編程的桌面程序;2)客戶端向服務器請求數據之前,服務器端不存在任何現成的緩存數據。

圖6 常規平臺與WebService優化平臺對于短時并發請求的查詢效率對比
實驗結果如圖6所示。其中,運用常規方法統計數據的客戶端在并發數量達到400個時,出現了大量數據庫連接超時的情形,并且隨著并發請求數量的不斷增加,單個線程完成統計所需的平均耗時從最初的3~5 s延遲到了1 min多鐘,甚至無法完成統計。但基于web service技術來請求數據的客戶端因為收益于web平臺本身的并發特性優勢和一系列的優化措施,其工作效率幾乎不受請求客戶端數量的影響。最后,基于web service的客戶端再次向服務器請求相同的統計數時,由于服務器已有統計完成的緩存數據,400個并發線程請求完成的平均時間只需要15 ms。
通過對Phpcms系統的分析和內部數據模型的改造,建立了一個基于phpcms系統內核并且能夠實現Web Service技術的數據交互平臺。新平臺基于URL的路由機制使得數據交互能夠跨語言跨操作系統,新平臺基于數據庫多態性的機制實現了不同數據庫的協同開發。新平臺基于網絡語言的優化使得來自不同特性的客戶端請求有了一個高度整合和統一維護的平臺。
改造后的新平臺能使運行在不同機器上的不同應用無須借助附加的、專門的第三方軟件或硬件,就可相互交換數據或集成。系統本身也很容易部署, 因為它們基于一些常規的產業標準以及已有的一些技術,諸如XML、HTTP、PHP。它不僅具有良好的維護性和擴展性,它更為氣象部門的各個業務平臺在數據交互上提供了一個通用的機制,使得移動氣象平臺,桌面氣象平臺和網頁氣象平臺在交互上形成一個統一的整體,使我們的開發維護工作能夠基于3種平臺統籌兼顧。
[1] Ethan Cerami(美).Web Services Essentials[M].美國:O′Reilly,2003
[2] 沈伯青,楊宗凱.WEB服務的基石:UDDI技術[J].計算機工程與應用,2003:147-150.
[3] 鄧 瑩,馮向科.探討Web Service的關鍵技術及其實現[J].電腦知識與技術,2006(35):28.
2015-04-22