在當前這個互連網業務飛速發展時期,新的產品如雨後春筍般湧出,老產品線新業務也在不斷突破和嘗試。這就對快速開發迭代提出了更高的要求。
一、基礎運行環境
針對新產品的開發,必須能夠快速搭建一套LAMP架構。那麼無外乎選擇一個webserver,選擇一個php版本,選擇一個mysql版本,再選擇一個PHP開發架構和選擇一些php通用擴充和基礎庫等。這個過程讀者可能覺得已經很快了,能不能更快?
選擇的過程要求研發同學對相關技術方向有一定的積累,權衡利弊和優先點,又是一番調研和學習。如果有一鍵安裝程式,提供自動化安裝webserver,php,mysql,以及攜帶高效能靈活的php開發架構,並提供標準化、安全、常用的設定檔,可以大大縮短產品線LAMP系統調研的成本,縮短工作周期。
一鍵安裝四步驟:(1)下載;(2)少量配置;(3)make install;(4)start;(當然有end啦,簡單的營運工具),運行環境OK。
二、業務開發架構
社區產品線各自為政,封閉得開發各自的商務邏輯。而事實上,各個產品線之間存在很多通用商務邏輯處理,如session驗證、許可權判斷、參數驗證、日誌列印等。不同產品線,所有請求都需要做這些處理,能不能不重複開發?無線業務開發和PC上的商務邏輯有很多的不同,但不同產品線之間也有很多通用性。能不能不重複開發?
產品線在內部通常對這些通用邏輯的處理做了一定的抽象,設計為ActionChain的形式或者通過基類的方案。架構將更徹底:將這些所有請求都要處理的通用邏輯以商務邏輯架構的形式提供,研發同學只需要關注使用者請求專有的邏輯處理。
一個使用者請求的處理邏輯如下圖:藍色部分是控制器架構處理流程,綠色部分和控制器架構相結合,處理所有請求通用的商務邏輯。而真正需要研發同學關注和開發的該使用者請求專有的業務處理,即黃色部分(當然一個不僅僅是一個Action指令碼,一個請求的處理會橫向做mvc分層,這塊後續會有涉及。)
商務邏輯架構繼承在一鍵安裝程式中提供,簡簡單單就可以獲得。
原生的PHP業務和模板耦合很深,沒有做任何的分層設計,其結果是代碼的複用性差。這樣的原始的PHP系統現在已幾乎消亡。PHP開發架構統一處理路由、渲染、AutoLoad,通用商務邏輯的抽象和基礎庫的抽象,專有業務MVC分層,已大大加快了產品線商務邏輯的開發。如下圖所示:
從上而下,分別是接入層(高效能webserver),PHP開發架構(路由、自動載入、視圖引擎等),應用和基礎庫,儲存引擎。
三、泛型服務
社區產品線存在很多共同的需求,如Tlog、設定檔的處理、字串處理、資料庫互動、網路互動等。這些演算法和工具封裝成phplib給產品線使用已比較成熟。
社區類產品線的業務功能存在很多的通用性,諸如評論功能、Tag功能、好友功能、圖冊、任務系統等,在眾多社區產品線都有類似的新功能新需求,各自設計開發?
這些需求在各產品線的UI上有個人化需求,但是後端實現方案大同小異,具有一定的通用性。功能服務化,提供API介面給不同產品線使用,產品線只需要關注展現邏輯和私人資料的處理邏輯即可,且服務統一營運,降低產品下的系統複雜度。
四、垂直分割子系統
那麼隨著我們業務的拓展,單個應用內部的ui和module的數量越來越多,Action和Logic(對應MVC中的M層,內部可以再進一步做分層處理,此次不詳述)的互動,logic和logic之間的互動變得越來越複雜。開發同學需要瞭解整個應用的邏輯,某個logic的升級,需要排查整個應用下是否存在其他ui或logic的反向依賴。在快速開發的要求下,開發同學對logic之間的相互耦合關係的梳理不清楚,勢必引發越來越多的問題,影響項目品質,難以開始開發。
單一系統的問題暴露越來越多,就到了系統拆分的時候了。如何拆?按商務邏輯垂直分割。將功能獨立的商務邏輯剝離出來,做成獨立的子系統。這個時候還需要考慮業務的通用性,是否可以服務化?應用已有相同需求的泛型服務?此時通用商務邏輯封裝成泛型服務或使用了泛型服務,旁路的商務邏輯獨立成子系統,如此一來就將原先單一龐大的系統做了大量減負。完成此階段的重構後,系統加入變成如下
單一系統被拆分成多個APP(APP內部仍然有橫向的MVC分層),並複用大量的泛型服務。如此一來研發團隊在人員分工並行開發上都得到了極大提高。
五、跨系統調用架構
然而真實的現狀,在拆分後的子系統之間並不能完全消除依賴。為瞭解決多個子系統之間資料依賴的關係,需要一套統一的解決方案:API架構。子系統成為獨立的應用(APP),APP之間存在相互的資料依賴,這些依賴以API的形式對外提供。如下圖
當APP1依賴APP2或APP3的資料後,APP2和APP3會將一部分資料介面以API的形式提供,資料做統一的打包,通過標準規範的URL提供產品線內部其他APP調用。這種形式非常類似於一個產品對外開放API(對第三方開放API,我們稱為openAPI,遵守統一的協議,並經過必要的許可權驗證),而解決內部子系統之間資料依賴的API介面可以進一步簡化。
APP提供的API解決提供介面描述(輸入、輸出),處理API的URL,Logic的轉寄實現。API_LIB統一來管理所有的API介面,並提供統一的API_Server::call介面供調用。完全對上屏蔽內部的轉寄和實現細節。通常產品線內部為了達到營運的簡化和統一,所有的子系統是同機部署的,API介面的會帶來額外的網路消耗,以及增大qps。在此部署前提下,API_Server的實現方式可以通過HTTP調用或最佳化為直接PHPRequire方式實現。優勢:
(1)架構統一,介面收斂,業務解耦;(2)效能提升,易用性高,擴充性高;
六、UI拆分模型
此時獨立出來的子系統可以專註做其商務邏輯了,核心的系統也得到減負。但是核心系統的升級更新頻率是最高的,商務邏輯也最複雜。到了一定時期,核心系統又變得臃腫,難以維護。此時可以通過一些設計模式來降低程式的可擴充性和可維護性。但即便是如此,還是有一定的學習成本,在一個App內部,開發同學或多或少需要關注其他模組的代碼,逐漸發展為升級一點就需要排查很多點。這時候又到了進一步減負的時候。如果減負?分為兩部:
第一步:非同步模型
頁面渲染分為兩個階段:主題頁面資料和其他非主題頁面資料。根據頁面的不同部分由不同的資料來源提供資料。按此邏輯將app進一步做垂直分割。
PHPService是由PHPmodule+一層很薄的UI,返回格式化資料。
第二步:同步模型
Module做拆分,不同商務邏輯拆分為不同的Module,區分為多個資料來源,分別提供不同資料內容,由統一的UI調度不同的資料來源後,統一進行渲染頁面返迴響應。
如此持續減負後,產品線內部的子系統和模組將越來越多,需要維持部署和營運的統一。對團隊成員的分工很細,業務理解很專註和深入,合作、並行的效率也會更高,從而使整個開發週期縮短。
七、 小結
隨著商務邏輯的不端壯大,每個子系統或模組的業務功能如果過於臃腫就需要不斷做減分,以保持在可控的規模內。如此隨著產品的發展,產品線內部的子系統和模組將越來越多,需要維持部署和營運的統一,保持簡單。對團隊成員的分工更細,業務理解保持專註和深入,合作、並行的效率也會更高,從而使整個開發週期縮短。