CMS即內容管理系統(Content Management System),目的是用於快速進行網站建設或者網頁開發。對於京東網站部門來講,CMS核心目的是用來快速開發和上線各類頁面,諸如各類垂直頻道頁,訪問www.jd.com將看到以下頁面,如點擊「服裝城」、「家用電器」等都會跳轉到一個垂直頻道頁;這些頁面中有許多頁面風格是相似的,所以很適合使用CMS進行快速搭建。php
對於咱們來講,CMS最核心的目的就是進行數據和模板的統一管理、頁面的統一發布,從而減小以前的不少重複工做。css
京東CMS是2014年提出來的,通過兩年多的完善,目前已經發展爲一個集標準服務管理、標準組件服務和智能投放於一體的標準化導購運營系統。具備如下特色:前端
1. 搭建快速,統一發布,統一架構;mysql
2. 先後端分離,後端再也不負責頁面渲染,只提供高性能、可複用的API;nginx
3. 移動端頁面支持;redis
4. 數據分析、智能投放的特色;sql
業務支持場景:數據庫
首頁、頻道頁、垂直頁、活動頁的搭建及單品頁、列表頁部分可維護的業務等。json
從基本功能及架構來看,能夠分爲 三個階段:後端
CMS 1.0——虛擬分類系統
CMS 2.0——CMS系統
CMS 3.0——CMS-portal系統
虛擬分類系統是一個獨立的促銷商品、促銷文字維護系統,與具體前端業務架構脫離,哪條線接入虛擬分類,須要根據本身的業務邏輯單獨開發、維護、部署本身的架構。說白了,虛擬分類系統提供一些基礎數據;而後好比我要搭建一個家電頻道頁,則須要開發一個Web項目,而後調用虛擬分類系統獲取數據而後進行模板渲染處理處理。所以虛擬分類系統當時只是一個基礎數據維護平臺,沒法實現信息的共享、複用和集約化管理。這就會存在各類各樣的頻道頁系統,致使管理混亂,性能上各有差別,出現過不少次事故。並且各系統須要獨立配置,致使工做量大,佔用資源多,沒法快速響應業務需求。
下圖是當時不一樣業務體系的架構:
能夠看出部分頻道頁和活動頁用的nginx+tomcat,部分頻道及垂直站用的nginx+php-fpm,與虛擬分類聯繫不大,整體遵循各業務層獲取虛擬分類的數據,分別獨立上線、部署、維護,應用層直連mysql,mysql 抗不住,會增長一層 memcache。
Cms2.0 總結了1.0時的不足,從節省資源、控制成本的角度考慮,把導購類的個體頁面業務進行了統一,模板能複用的複用,之前虛擬分類系統的頻道也須要遷移到新的系統。
咱們作了如下改動:
1. CMS 2.0數據結構適合虛擬分類體系,方便新老數據兼容;
2. 升級架構,統一配置、發佈流程;去memcache爲redis,作大量性能壓測來調優php-fpm配置,單機TPS能達到3000+; 配置定時任務,保證redis數據實時性;
3. 單點發布,一鍵預覽加強採銷維護數據的機動性;
4. 單機閉環,單機閉環服務設計是CMS總體架構的核心部分,須要展現的內容在本機獲取、封裝、校驗;
5. 模塊化、動態數據類型初期版本(CMS 3.0會細說);
架構圖:
對比1.0,新的CMS可讓頻道頁的開發週期下降2~4周,大大提升了業務需求的響應速度;它看起來更獨立,更像一個總體,在容災、規避風險方面作了嚴謹的優化;同時讓採銷在維護數據時,更方便、更簡單。
後續因爲個性化的需求愈來愈多,大量的頻道業務須要開發人員一個一個套模板來實現,大大加大了開發人員的工做強度,以前的模板複用方式已經沒法知足業務的需求,同時太簡單的數據模塊,須要手工來綁定數據類型也增長了開發成本,這時候須要咱們必須作出改變。
CMS 2.0後也存在不少痛點,所以咱們也想在CMS 3.0上解決這些問題:
1. 本質問題就是要快:快速支持、響應業務愈來愈多的垂直化頁面改版;
2. 先後端分離,頁面渲染讓前端實現,解放後端讓後端作高大上的事情;
3. 減輕運營人員的工做量,系統簡單好用,提升導購類商品的轉化率;
4. 其餘系統的支撐,實現CMS的集約化管理;
5. AB測試;
6. 兼容手機端;
7. 站點管理、統一架構、容災、高性能、水平擴容;
經過兩版CMS系統的開發,咱們發現CMS無外乎管理的是數據和模板,另外須要好的預覽、一鍵發佈支持。而傳統數據管理都是靜態數據類型,而咱們作了動態數據類型的設計;另外咱們作了模板管理中心,並抽象了模板、樓層、元件、模塊的概念,從而實現更好的複用性。
主要分爲以下幾部分
CMS系統:統一管理CMS相關數據,並進行頁面的生成和發佈;
數據Worker管理中心:調用第三方服務進行數據校驗(如庫存不足補貨),並調用CMS系統進行頁面生成和發佈,發佈到單點服務器上;
單點服務器:相關頁面的單機閉環實現,即CMS發佈的頁面會存儲在這些單點服務器上;每一個機房會部署一臺;
頁面定時更新Worker:按期同步單點服務器內容到靜態應用服務器集羣,並保存歷史版本,當出現問題時能夠切換回上一個版本;
靜態應用服務器集羣:靜態託底實現,會存儲相關的靜態頁面文件,當單點服務器掛了時,降級到該集羣;
異步加載的個性化服務:有些數據不能存儲到靜態頁,如價格/庫存/推薦等數據,此時經過異步加載這些數據,實現個性化服務;
接入層Nginx:接入層Nginx負責請求的路由和服務的降級。
1. 引入動態數據類型;
2. 頁面模板管理中心,模板、樓層、元件、模塊設計,實現可複用;
3. 使用元件實現先後端分離;
4. 動態服務和業務數據閉環;
5. 預覽、一鍵發佈,單點管理;
6. H5版直接搭建,native版 API 支持;
7. 大數據智能選品應用;
所謂的動態是指能靈活擴展的,不須要上線也不須要修改數據庫字段,支持自由擴展;這樣作的好處是可以快速響應電商網站的日益靈活多變的促銷需求。好比促銷語:
目前經常使用的數據類型爲文字鏈、小圖文、商品池等。
數據結構:
操做界面:
使用動態數據類型定義了數據以後,須要在模板中使用它。而在咱們CMS系統中進行了頁面、模板、樓層、元件、模塊的劃分。模塊是某種數據類型的具體化,即有了數據的數據類型。元件是由模塊和HTML代碼段(根據模塊數據進行渲染的一小段模板)組成;樓層經過一系列元件組成,而模板會引入多個樓層,固然也會引入一些JS、CSS等,最終經過模板渲染出相應頁面。
有了這個元件以後,就能夠完全解放後端,頁面渲染工做徹底交由前端來開發,實現了先後端的分離。
即CMS研發只負責平臺和基礎數據的維護,業務人員進行模塊的維護,而前端人員獨立完成元件開發、模板設計、開發和發佈。
跨線條業務間的資源複用、獨立調用時須要提供相關的API,如三級地址服務,類目服務、動態加載的數據(如爆款特賣、今日推薦等)等。數據格式知足數據閉環原則。Lua+redis架構實現,單機(16U)QPS能達到20000+。
頻道業務數據閉環
數據閉環,即數據的自我管理,或者說數據都在本身系統維護,不依賴與其餘任何系統,去依賴化,這樣獲得的好處是別人抖動與我不要緊。所以咱們先要數據異構。
數據異構是數據閉環的第一步,將依賴系統的數據拿過來,按照本身的業務需求存儲起來。頻道業務須要異構的數據主要是三部分:商品基本信息、第三方數據、大數據。
數據原子化處理,數據異構的數據是原子化數據,這樣將來咱們能夠對這些數據再加工再處理而響應變化的需求。咱們有了一份原子化異構數據雖然方便處理新需求,但偏偏由於第一份數據是原子化的,那麼它會很分散,前端讀取時mget的話 性能不是很好,所以咱們又作了數據聚合。
數據聚合,是將多個原子數據聚合爲一個大JSON數據,這樣前端展現只須要一次get,固然要考慮系統架構,好比咱們使用的Redis改造,Redis又是單線程系統,咱們須要部署更多的Redis來支持更高的併發,另外存儲的值要儘量的小。
應用層容災
1. 數據校驗,CMS在頁面預覽有一層嚴格的數據校驗邏輯,好比數據格式、數據大小、敏感詞等,保證頁面生成100%沒有問題。
2. 版本降級,靜態頁面出現問題,除了頁面自己數據有問題外,潛入的js、css出現問題也會影響頁面展現,這時候會版本下降爲前一天的正確版本;
3. 異步服務,異步化數據容災方面主要是監聽服務的狀態及響應時間;降級訪問有隱藏該功能和切換服務器實現;
服務器容災
主要是經過多機房部署,監控80端口,出現問題能夠自動把流量水平切走。
智能選品,是服務於前臺的流量運營,爲採銷及運營人員提供運營支持,爲每一次訪問提供最合適和匹配的商品、品牌以及促銷活動。是根據用戶的行爲推薦出相關的商品及活動。能夠分爲羣體特徵和個體特徵。羣體特徵分爲兩部分,數據部分及規則部分。
數據部分是從大數據平臺異構過來,固然這個數據是海量的,咱們選擇熱點TOP 5000的數據來異構。
規則部分是經過京智後臺建立,在審覈經過後,觸發MQ,經過ES 跑出對應數據,而後由頻道頁動態服務系統對外提供json格式的http服務。前端業務以異步的方式傳遞相關規則參數進行調用。
智能選品實現數據化、定製化、個性化、自動及半自動化內容運營。它能夠模擬人腦選貨邏輯,以運營指標爲導向(GMV、訂單轉化率、點擊量、毛利等),分區域、分用戶選取最匹配的內容。目前應用於京東超市、行業頻道以及618大促主會場,帶來優於人工選品的轉化效果,並解放採銷運營人員平常繁瑣的運營工做,提升了總體效率。
rsync文件同步
上面的介紹過,咱們的靜態頁面爲了保持數據的一致性由單點服務器經過rsync同步靜態文件到其餘服務器,有時候會發現服務器負載無故的被打滿。
分析問題發現若是定時任務腳本的同步未在規定時間內完成,crontab接下來的還會執行此腳本,這樣就會產生相同的rsync的進程。按照這種狀態,長時間就會衍生出不少個rsync進程,就會致使負載太高,甚至有些服務器會掛掉。這時候咱們用到了rsync的進程鎖,在目錄下生成一個rsync.lock文件,當crontab執行時,rsync會判斷鎖文件是否存在,若是存在說明本次同步未完成,則不執行rsync。
數據必定要閉環
別人的接口抖動以及返回數據的異常,影響到前端展現對咱們來講說是不能容忍的,這就須要咱們針對各類狀況一一校驗。
目前經過CMS搭建、正在搭建以及使用CMS API支持的PC端、移動端頁面粗略估計約有上千,這對CMS來講意義重大,隨着業務需求量的愈來愈大,也給咱們帶來了新的指望。接下來,咱們會從可視化編輯、數據統計分析、關鍵詞管理、商品下架預警等方面進行相關的優化工做。