Repractise架構篇一:CMS的重構與演進

佚名發表於2015-11-18

重構系統是一項非常具有挑戰性的事情。通常來說,在我們的系統是第二個系統的時候才需要重構,即這個系統本身已經很臃腫。我們花費了太量的時間在程式碼間的邏輯,開發新的功能變得越來越慢。這不僅僅可能只是因為我們之前的架構沒有設計好,而且在我們開發的過程中沒有保持著原先設計時的一些原則。如果是這樣的情況,那麼這就是一個複雜的過程。

還有一種情況是我們發現了一種更符合我們當前業務的框架。

動態CMS

CMS簡介

CMS是Content Management System的縮寫,意為"內容管理系統".它可以做很多的事情,但是總的來說就是Page和Blog——即我們要建立一些頁面可以用於寫一些About US、Contact Me,以及持續更新的部落格或者新聞,以及其他子系統——通常更新不活躍。透過對這些部落格或者新聞進行分類,我們就可以有不同的資訊內容,如下圖:

CMS系統 CMS建站系統 CMS內容管理系統 重構系統

CMS是政府和企業都需要的系統,他們有很多的資訊需要公開,並且需要對其組織進行宣傳。在我有限的CMS交付經驗裡(大學時期),一般第一次交付CMS的時候,已經建立了大部分頁面。有時候這些頁面可能直接儲存在資料庫中,後來發現這不是一個好的方案,於是很多頁面變成了靜態頁面。隨後,在CMS的生命週期裡就是更新內容。

因而,CMS中起其主導的東西還是Content,即內容。而內容是一些持續可變的東西。這也就是為什麼wordPress這麼流行於CMS界,它是一個部落格系統,但是多數時候我們只需要更新內容。除此不得不提及的一個CMS框架是Drupal,兩者一對比會發現Drupal比較強大。通常來說,強大的一個負作用就是——複雜。

WordPress和Drupal這一類的系統都屬於釋出系統,而其後臺可以稱為編輯系統。

一般來說CMS有下面的特點:

  • 支援多使用者。
  • 角色控制-內容管理。如InfoQ的編輯後臺就會有這樣的機制,社群編輯負責建立內容,而稽核釋出則是另外的人做的。
  • 外掛管理。如WordPress和Drupal在這一方面就很強大,基本可以滿足日常的需要。
  • 快捷簡便地儲存內容。簡單地來說就是所見即所得編輯器,但是對於開發者來說,Markdown似乎是好的選擇。
  • 預釋出。這是一個很重要的特性,特別是如果你的系統後臺沒有相對應的預覽機制。
  • 子系統。由於這屬於定製化的系統,並不方便進行總結。
  • ...

CMS一直就是這樣一個緊耦合的系統。

CMS架構與Django

說起來,我一直是一個CMS黨。主要原因還在於我可以隨心所欲地去修改網站的內容,修改網站的架構。好的CMS總的來說都有其架構圖,下圖似乎是Drupal的模組圖

CMS系統 CMS建站系統 CMS內容管理系統 重構系統

一般來說,其底層都會有:

  • ORM
  • User Management
  • I18n / L10n
  • Templates

我一直在使用一個名為Django的Python Web框架,它最初是被開發來用於管理勞倫斯出版集團旗下的一些以新聞內容為主的網站的,即是CMS(內容管理系統)軟體。它是一個MTV框架——與多數的框架並沒有太大的區別。

層次職責 模型(Model),即資料存取層 處理與資料相關的所有事務:如何存取、如何驗證有效性、包含哪些行為以及資料之間的關係等。 模板(Template),即表現層 處理與表現相關的決定: 如何在頁面或其他型別文件中進行顯示。 檢視(View),即業務邏輯層 存取模型及調取恰當模板的相關邏輯。模型與模板之間的橋樑。

從框架本身來上看它和別的系統沒有太大的區別。

CMS系統 CMS建站系統 CMS內容管理系統 重構系統

但是如果我們已經有多外模組(即Django中app的概念),那麼系統的架構就有所不同了。

CMS系統 CMS建站系統 CMS內容管理系統 重構系統

這就是為何我喜歡用這個CMS的原因了,我的每個子系統都以APP的形式提供服務——部落格是一個app,sitemap是一個app,api是一個app。系統直接解耦為類似於混合服務的架構,即不像微服務一樣多語言化,又不會有宏應用的緊耦合問題。

編輯-釋出分離

我們的編輯和釋出系統在某種意義上緊耦合在一起了,當使用者訪問量特別大的時候,這樣會讓我們的應用變得特定慢。有時候編輯甚至釋出不了新的東西,如下圖引示:

CMS系統 CMS建站系統 CMS內容管理系統 重構系統

或者你認識出了上圖是源自Martin Folwer的編輯-釋出分離

編輯-釋出分離是幾年前解耦複雜系統游來開來帶來的一個成果。今天這個似乎已經很常見了,編輯的時候是在後臺進行的,等到釋出的時候已經變成了一個靜態的HTML。

已經有足夠多的CMS支援這樣的特性,執行起來似乎特別不錯,當然這樣的系統也會有快取的問題。有了APP這後,這個趨勢就更加明顯了——人們需要提供一個API。到底是在現有的系統裡提供一個新的API,還是建立一個新的API。

這時候,我更願意選擇後者——畢竟緊耦合一個系統總會在後期帶來足夠多的麻煩。而且基於資料庫構建一個只讀的RESTful API並不是一個複雜的過程,而且也危險。這時候的瓶頸就是資料庫,但是似乎資料庫都是多數系統的瓶頸。人們想出了各種各樣的技術來解決這個瓶頸。

於是之前我試著用Node.js + RESTify將我的部落格重構成了一個SPA,當然這個時候CMS還在執行著。出於SEO的原因我並沒有在最後採用這個方案,因為我網站的主要流量來源是Google和是百度。但是我在另外的網站裡混合了SPA與MPA,其中的效能與應用是相當的,除了第一次載入頁面的時候會帶來一些延時。

除了Node.js + RESTify,也試了試Python + Falcon(一個高效能的RESTful框架)。這個API理論上也應該可以給APP直接使用,並且可以直接拿來生成靜態頁面。

相關文章