重構(gòu)系統(tǒng)是一項非常具有挑戰(zhàn)性的事情。通常來說,在我們的系統(tǒng)是第二個系統(tǒng)的時候才需要重構(gòu),即這個系統(tǒng)本身已經(jīng)很臃腫。我們花費了太量的時間在代碼間的邏輯,開發(fā)新的功能變得越來越慢。這不僅僅可能只是因為我們之前的架構(gòu)沒有設(shè)計好,而且在我們開發(fā)的過程中沒有保持著原先設(shè)計時的一些原則。如果是這樣的情況,那么這就是一個復(fù)雜的過程。 還有一種情況是我們發(fā)現(xiàn)了一種更符合我們當(dāng)前業(yè)務(wù)的框架。 動態(tài)CMSCMS簡介CMS是Content Management System的縮寫,意為”內(nèi)容管理系統(tǒng)”.它可以做很多的事情,但是總的來說就是Page和Blog——即我們要創(chuàng)建一些頁面可以用于寫一些About US、Contact Me,以及持續(xù)更新的博客或者新聞,以及其他子系統(tǒng)——通常更新不活躍。通過對這些博客或者新聞進(jìn)行分類,我們就可以有不同的信息內(nèi)容,如下圖: CMS是政府和企業(yè)都需要的系統(tǒng),他們有很多的信息需要公開,并且需要對其組織進(jìn)行宣傳。在我有限的CMS交付經(jīng)驗里(大學(xué)時期),一般第一次交付CMS的時候,已經(jīng)創(chuàng)建了大部分頁面。有時候這些頁面可能直接存儲在數(shù)據(jù)庫中,后來發(fā)現(xiàn)這不是一個好的方案,于是很多頁面變成了靜態(tài)頁面。隨后,在CMS的生命周期里就是更新內(nèi)容。 因而,CMS中起其主導(dǎo)的東西還是Content,即內(nèi)容。而內(nèi)容是一些持續(xù)可變的東西。這也就是為什么WordPress這么流行于CMS界,它是一個博客系統(tǒng),但是多數(shù)時候我們只需要更新內(nèi)容。除此不得不提及的一個CMS框架是Drupal,兩者一對比會發(fā)現(xiàn)Drupal比較強(qiáng)大。通常來說,強(qiáng)大的一個負(fù)作用就是——復(fù)雜。 WordPress和Drupal這一類的系統(tǒng)都屬于發(fā)布系統(tǒng),而其后臺可以稱為編輯系統(tǒng)。 一般來說CMS有下面的特點:
CMS一直就是這樣一個緊耦合的系統(tǒng)。 CMS架構(gòu)與Django說起來,我一直是一個CMS黨。主要原因還在于我可以隨心所欲地去修改網(wǎng)站的內(nèi)容,修改網(wǎng)站的架構(gòu)。好的CMS總的來說都有其架構(gòu)圖,下圖似乎是Drupal的模塊圖 一般來說,其底層都會有:
我一直在使用一個名為Django的Python Web框架,它最初是被開發(fā)來用于管理勞倫斯出版集團(tuán)旗下的一些以新聞內(nèi)容為主的網(wǎng)站的,即是CMS(內(nèi)容管理系統(tǒng))軟件。它是一個MTV框架——與多數(shù)的框架并沒有太大的區(qū)別。
從框架本身來上看它和別的系統(tǒng)沒有太大的區(qū)別。 但是如果我們已經(jīng)有多外模塊(即Django中app的概念),那么系統(tǒng)的架構(gòu)就有所不同了。 這就是為何我喜歡用這個CMS的原因了,我的每個子系統(tǒng)都以APP的形式提供服務(wù)——博客是一個app,sitemap是一個app,api是一個app。系統(tǒng)直接解耦為類似于混合服務(wù)的架構(gòu),即不像微服務(wù)一樣多語言化,又不會有宏應(yīng)用的緊耦合問題。 編輯-發(fā)布分離我們的編輯和發(fā)布系統(tǒng)在某種意義上緊耦合在一起了,當(dāng)用戶訪問量特別大的時候,這樣會讓我們的應(yīng)用變得特定慢。有時候編輯甚至發(fā)布不了新的東西,如下圖引示: 或者你認(rèn)識出了上圖是源自Martin Folwer的編輯-發(fā)布分離 編輯-發(fā)布分離是幾年前解耦復(fù)雜系統(tǒng)游來開來帶來的一個成果。今天這個似乎已經(jīng)很常見了,編輯的時候是在后臺進(jìn)行的,等到發(fā)布的時候已經(jīng)變成了一個靜態(tài)的HTML。 已經(jīng)有足夠多的CMS支持這樣的特性,運行起來似乎特別不錯,當(dāng)然這樣的系統(tǒng)也會有緩存的問題。有了APP這后,這個趨勢就更加明顯了——人們需要提供一個API。到底是在現(xiàn)有的系統(tǒng)里提供一個新的API,還是創(chuàng)建一個新的API。 這時候,我更愿意選擇后者——畢竟緊耦合一個系統(tǒng)總會在后期帶來足夠多的麻煩。而且基于數(shù)據(jù)庫構(gòu)建一個只讀的RESTful API并不是一個復(fù)雜的過程,而且也危險。這時候的瓶頸就是數(shù)據(jù)庫,但是似乎數(shù)據(jù)庫都是多數(shù)系統(tǒng)的瓶頸。人們想出了各種各樣的技術(shù)來解決這個瓶頸。 于是之前我試著用Node.js + RESTify將我的博客重構(gòu)成了一個SPA,當(dāng)然這個時候CMS還在運行著。出于SEO的原因我并沒有在最后采用這個方案,因為我網(wǎng)站的主要流量來源是Google和是百度。但是我在另外的網(wǎng)站里混合了SPA與MPA,其中的性能與應(yīng)用是相當(dāng)?shù)?,除了第一次加載頁面的時候會帶來一些延時。 除了Node.js + RESTify,也試了試Python + Falcon(一個高性能的RESTful框架)。這個API理論上也應(yīng)該可以給APP直接使用,并且可以直接拿來生成靜態(tài)頁面。 編輯-發(fā)布-開發(fā)分離:靜態(tài)站點生成如React一樣解決DOM性能的問題就是跳過DOM這個坑,要跳過動態(tài)網(wǎng)站的性能問題就是讓網(wǎng)站變成靜態(tài)。 越來越多的開發(fā)人員開始在使用Github Pages作為他們的博客,這是一個很有意思的轉(zhuǎn)變。主要的原因是這是免費的,并且基本上可以保證24x7小時是可用的——當(dāng)且僅當(dāng)Github發(fā)現(xiàn)故障的時候才會不可訪問。 在這一類靜態(tài)站點生成器(Github)里面,比較流行的有下面的內(nèi)容(數(shù)據(jù)來源: http://segmentfault.com/a/1190000002476681):
通常這一類的工具里會有下面的內(nèi)容:
如Hexo這樣的框架甚至提供了 在我們寫了相關(guān)的代碼之后,隨后要做的就是生成HTML。對于個人博客來說,這是一個非常不錯的系統(tǒng),但是對于一些企業(yè)級的系統(tǒng)來說,我們的要求就更高了。如下圖是Carrot采用的架構(gòu): 這與我們在項目上的系統(tǒng)架構(gòu)目前相似。作為一個博主,通常來說我們修改博客的主題的頻率會比較低, 可能是半年一次。如果你經(jīng)常修改博客的主題,你博客上的文章一定是相當(dāng)?shù)纳佟?/p> 上圖中的編輯者通過一個名為Contentful CMS來創(chuàng)建他們的內(nèi)容,接著生成RESTful API。而類似的事情,我們也可以用Wordpress + RESTful 插件來完成。如果做得好,那么我想這個API也可以直接給APP使用。 上圖中的開發(fā)者需要不斷地將修改的主題或者類似的東西PUSH到版本管理系統(tǒng)上,接著會有webhook監(jiān)測到他們的變化,然后編譯出新的靜態(tài)頁面。 最后通過Netlify,他們編譯到了一起,然后部署到生產(chǎn)環(huán)境。除了Netlify,你也可以編寫生成腳本,然后用Bamboo、Go這類的CI工具進(jìn)行編譯。 通常來說,生產(chǎn)環(huán)境可以使用CDN,如CloudFront服務(wù)。與動態(tài)網(wǎng)站相比,靜態(tài)網(wǎng)站很容易直接部署到CDN,并可以直接從離用戶近的本地緩存提供服務(wù)。除此,直接使用AWS S3的靜態(tài)網(wǎng)站托管也是一個非常不錯的選擇。 基于Github的編輯-發(fā)布-開發(fā)分離盡管我們已經(jīng)在項目上實施了基于Github的部分內(nèi)容管理已經(jīng)有些日子里,但是由于找不到一些相關(guān)的資料,便不好透露相關(guān)的細(xì)節(jié)。直到我看到了《An Incremental Approach to Content Management Using Git 1》,我才意識到這似乎已經(jīng)是一個成熟的技術(shù)了??礃幼舆@項技術(shù)首先已經(jīng)應(yīng)用到了ThoughtWorks的官網(wǎng)上了。 文中提到了使用這種架構(gòu)的幾個點:
So,so,這些開發(fā)人員做了些什么:
于是,有了一個名為Hacienda的框架用于管理內(nèi)容,并存儲為JSON。這意味著什么? 因為使用了Git,我們可以了解到一個文件內(nèi)容的歷史版本,相比于WordPress來說更直觀,而且更容易 上手。 開發(fā)人員修改完他們的代碼后,就可以直接提交,不會影響到Editor使用網(wǎng)站。Editor通過一個編輯器添加內(nèi)容,在保存后,內(nèi)容以JSON的形式出現(xiàn)直接提交代碼到Github上相應(yīng)的代碼庫中。CI或者Builder監(jiān)測到他們的辦法,就會生成新的靜態(tài)頁面。在這時候,我們可以選擇有一個預(yù)覽的平臺,并且可以一鍵部署。那么,事情似乎就完成得差不多了。 如果我們有APP,那么我們就可以使用Content Servies來做這些事情。甚至可以直接拿其搭建一個SPA。 如果我們需要全文搜索功能,也變得很簡單。我們已經(jīng)不需要直接和數(shù)據(jù)庫交互,我們可以直接讀取JSON并且構(gòu)建索引。這時候需要一個簡單的Web服務(wù),而且這個服務(wù)還是只讀的。 在需要的時候,如手機(jī)APP,我們可以通過Content Servies來創(chuàng)建博客。 Repractise思考完這些后,我想到了一個符合學(xué)習(xí)的場景。 我們構(gòu)建的核心都可以基于Travis CI來完成,唯一存在風(fēng)險的環(huán)節(jié)是我們似乎需要暴露我們的Key。 其他原文: Repractise架構(gòu)篇一: CMS的重構(gòu)與演進(jìn) 參考文章: |
|