京東上千頁面搭建基石——CMS前後端分離演進史
宣告:本文來自京東張開濤的微信公眾號(kaitao-1234567),授權CSDN轉載,如需轉載請聯絡作者。
作者:於林坤,2012年加入京東,網站移動研發部頻道業務技術負責人,先後多次主導京東商城首頁、頻道頁技改及架構升級,在高併發系統架構、前端系統架構與優化方面有豐富經驗,PHPer。
責編:錢曙光,關注架構和演算法領域,尋求報導或者投稿請發郵件qianshg@csdn.net,另有「CSDN 高階架構師群」,內有諸多知名網際網路公司的大牛架構師,歡迎架構師加微信qshuguang2008申請入群,備註姓名+公司+職位。
京東CMS簡介
CMS即內容管理系統(ContentManagementSystem),目的是用於快速進行網站建設或者網頁開發。對於京東網站部門來說,CMS核心目的是用來快速開發和上線各種頁面,諸如各種垂直頻道頁,訪問www.jd.com將看到如下頁面,如點選“服裝城”、“家用電器”等都會跳轉到一個垂直頻道頁;這些頁面中有許多頁面風格是類似的,因此很適合使用CMS進行快速搭建。
對於我們來說,CMS最核心的目的就是進行資料和模板的統一管理、頁面的統一發布,從而減少之前的很多重複工作。
京東CMS是2014年提出來的,經過兩年多的完善,目前已經發展為一個集標準服務管理、標準元件服務和智慧投放於一體的標準化導購運營系統。具有以下特點:
- 搭建快速,統一發布,統一架構;
- 前後端分離,後端不再負責頁面渲染,只提供高效能、可複用的API;
- 移動端頁面支援;
- 資料分析、智慧投放的特點。
業務支援場景:
首頁、頻道頁、垂直頁、活動頁的搭建及單品頁、列表頁部分可維護的業務等。
從基本功能及架構來看,可以分為三個階段:
CMS 1.0——虛擬分類系統
CMS 2.0——CMS系統
CMS 3.0——CMS-portal系統
CMS 1.0—虛擬分類系統
虛擬分類系統是一個獨立的促銷商品、促銷文字維護系統,與具體前端業務架構脫離,哪條線接入虛擬分類,需要根據自己的業務邏輯單獨開發、維護、部署自己的架構。說白了,虛擬分類系統提供一些基礎資料;然後比如我要搭建一個家電頻道頁,則需要開發一個Web專案,然後呼叫虛擬分類系統獲取資料然後進行模板渲染處理處理。因此虛擬分類系統當時只是一個基礎資料維護平臺,無法實現資訊的共享、複用和集約化管理。這就會存在各種各樣的頻道頁系統,導致管理混亂,效能上各有差異,出現過很多次事故。而且各系統需要獨立配置,導致工作量大,佔用資源多,無法快速響應業務需求。
下圖是當時不同業務體系的架構:
可以看出部分頻道頁和活動頁用的nginx+tomcat,部分頻道及垂直站用的nginx+php-fpm,與虛擬分類聯絡不大,總體遵循各業務層獲取虛擬分類的資料,分別獨立上線、部署、維護,應用層直連mysql,mysql 抗不住,會增加一層 memcache。
CMS 2.0—CMS系統
Cms2.0總結了1.0時的不足,從節省資源、控制成本的角度考慮,把導購類的個體頁面業務進行了統一,模板能複用的複用,以前虛擬分類系統的頻道也需要遷移到新的系統。
我們做了以下改動:
CMS 2.0資料結構適合虛擬分類體系,方便新老資料相容;
升級架構,統一配置、釋出流程;去memcache為redis,做大量效能壓測來調優php-fpm配置,單機TPS能達到3000+; 配置定時任務,保證redis資料實時性;
單點發布,一鍵預覽增強採銷維護資料的機動性;
單機閉環,單機閉環服務設計是CMS整體架構的核心部分,需要展示的內容在本機獲取、封裝、校驗;
模組化、動態資料型別初期版本(CMS 3.0會細說)。
架構圖:
對比1.0,新的CMS可以讓頻道頁的開發週期降低2~4周,大大提高了業務需求的響應速度;它看起來更獨立,更像一個整體,在容災、規避風險方面做了嚴謹的優化;同時讓採銷在維護資料時,更方便、更簡單。
後續由於個性化的需求越來越多,大量的頻道業務需要開發人員一個一個套模板來實現,大大加大了開發人員的工作強度,之前的模板複用方式已經無法滿足業務的需求,同時太簡單的資料模組,需要手工來繫結資料型別也增加了開發成本,這時候需要我們必須做出改變。
CMS 3.0—CMS-portal系統
CMS 2.0後也存在很多痛點,因此我們也想在CMS3.0上解決這些問題:
- 本質問題就是要快:快速支援、響應業務越來越多的垂直化頁面改版;
- 前後端分離,頁面渲染讓前端實現,解放後端讓後端做高大上的事情;
- 減輕運營人員的工作量,系統簡單好用,提高導購類商品的轉化率;
- 其他系統的支撐,實現CMS的集約化管理;
- 相容手機端;
- 站點管理、統一架構、容災、高效能、水平擴容。
通過兩版CMS系統的開發,我們發現CMS無外乎管理的是資料和模板,另外需要好的預覽、一鍵釋出支援。而傳統資料管理都是靜態資料型別,而我們做了動態資料型別的設計;另外我們做了模板管理中心,並抽象了模板、樓層、元件、模組的概念,從而實現更好的複用性。
統一架構
主要分為如下幾部分
CMS系統:統一管理CMS相關資料,並進行頁面的生成和釋出;
資料Worker管理中心:呼叫第三方服務進行資料校驗(如庫存不足補貨),並呼叫CMS系統進行頁面生成和釋出,釋出到單點伺服器上;
單點伺服器:相關頁面的單機閉環實現,即CMS釋出的頁面會儲存在這些單點伺服器上;每個機房會部署一臺;
頁面定時更新Worker:定期同步單點伺服器內容到靜態應用伺服器叢集,並儲存歷史版本,當出現問題時可以切換回上一個版本;
靜態應用伺服器叢集:靜態託底實現,會儲存相關的靜態頁面檔案,當單點伺服器掛了時,降級到該叢集;
非同步載入的個性化服務:有些資料不能儲存到靜態頁,如價格/庫存/推薦等資料,此時通過非同步載入這些資料,實現個性化服務;
接入層Nginx:接入層Nginx負責請求的路由和服務的降級。
主要思路
- 引入動態資料型別;
- 頁面模板管理中心,模板、樓層、元件、模組設計,實現可複用;
- 使用元件實現前後端分離;
- 動態服務和業務資料閉環;
- 預覽、一鍵釋出,單點管理;
- H5版直接搭建,native版 API 支援;
- 大資料智慧選品應用。
動態資料型別
所謂的動態是指能靈活擴充套件的,不需要上線也不需要修改資料庫欄位,支援自由擴充套件;這樣做的好處是能夠快速響應電商網站的日益靈活多變的促銷需求。比如促銷語:
目前常用的資料型別為文字鏈、小圖文、商品池等。
操作介面:
動態資料型別資料結構:
fields是json串,用於動態定義欄位。
使用元件實現前後端分離
使用動態資料型別定義了資料之後,需要在模板中使用它。而在我們CMS系統中進行了頁面、模板、樓層、元件、模組的劃分。模組是某種資料型別的具體化,即有了資料的資料型別。元件是由模組和HTML程式碼段(根據模組資料進行渲染的一小段模板)組成;樓層通過一系列元件組成,而模板會引入多個樓層,當然也會引入一些JS、CSS等,最終通過模板渲染出相應頁面。
type是資料型別表,module是模組表,source是資料表,按照上面的邏輯我們是通過資料型別獲取到資料模組,並同時能拿到該模組所對應的商品資料(商品池)。
有了這個元件之後,就可以徹底解放後端,頁面渲染工作完全交由前端來開發,實現了前後端的分離。
即CMS研發只負責平臺和基礎資料(動態服務)的維護,業務人員進行模組的維護,而前端人員獨立完成元件開發、模板設計、開發和釋出。
動態服務
跨線條業務間的資源複用、獨立呼叫時需要提供相關的API,如三級地址服務,類目服務、動態載入的資料(如爆款特賣、今日推薦等)等。資料格式滿足資料閉環原則。Lua+redis架構實現,單機(16U)QPS能達到20000+。
頻道業務資料閉環
資料閉環,即資料的自我管理,或者說資料都在自己系統維護,不依賴與其他任何系統,去依賴化,這樣得到的好處是別人抖動與我沒關係。因此我們先要資料異構。
資料異構是資料閉環的第一步,將依賴系統的資料拿過來,按照自己的業務需求儲存起來。頻道業務需要異構的資料主要是三部分:商品基本資訊、第三方資料、大資料。
資料原子化處理,資料異構的資料是原子化資料,這樣未來我們可以對這些資料再加工再處理而響應變化的需求。我們有了一份原子化異構資料雖然方便處理新需求,但恰恰因為第一份資料是原子化的,那麼它會很分散,前端讀取時mget的話 效能不是很好,因此我們又做了資料聚合。
資料聚合,是將多個原子資料聚合為一個大JSON資料,這樣前端展示只需要一次get,當然要考慮系統架構,比如我們使用的Redis改造,Redis又是單執行緒系統,我們需要部署更多的Redis來支援更高的併發,另外儲存的值要儘可能的小。
容災
應用層容災
- 資料校驗,CMS在頁面預覽有一層嚴格的資料校驗邏輯,比如資料格式、資料大小、敏感詞等,保證頁面生成100%沒有問題。
版本降級,靜態頁面出現問題,除了頁面本身資料有問題外,潛入的js、css出現問題也會影響頁面展示,這時候會版本降低為前一天的正確版本;
非同步服務,非同步化資料容災方面主要是監聽服務的狀態及響應時間;降級訪問有隱藏該功能和切換伺服器實現;
伺服器容災
主要是通過多機房部署,監控80埠,出現問題可以自動把流量水平切走。
智慧選品
智慧選品,是服務於前臺的流量運營,為採銷及運營人員提供運營支援,為每一次訪問提供最合適和匹配的商品、品牌以及促銷活動。是根據使用者的行為推薦出相關的商品及活動。可以分為群體特徵和個體特徵。群體特徵分為兩部分,資料部分及規則部分。
資料部分是從大資料平臺異構過來,當然這個資料是海量的,我們選擇熱點TOP 5000的資料來異構。
規則部分是通過京智後臺建立,在稽核通過後,觸發MQ,通過ES 跑出對應資料,然後由頻道頁動態服務系統對外提供json格式的http服務。前端業務以非同步的方式傳遞相關規則引數進行呼叫。
智慧選品實現資料化、定製化、個性化、自動及半自動化內容運營。它可以模擬人腦選貨邏輯,以運營指標為導向(GMV、訂單轉化率、點選量、毛利等),分割槽域、分使用者選取最匹配的內容。目前應用於京東超市、行業頻道以及618大促主會場,帶來優於人工選品的轉化效果,並解放採銷運營人員日常繁瑣的運營工作,提高了整體效率。
遇到的坑
rsync檔案同步
上面的介紹過,我們的靜態頁面為了保持資料的一致性由單點伺服器通過rsync同步靜態檔案到其他伺服器,有時候會發現伺服器負載無端的被打滿。
分析問題發現如果定時任務指令碼的同步未在規定時間內完成,crontab接下來的還會執行此指令碼,這樣就會產生相同的rsync的程式。按照這種狀態,長時間就會衍生出很多個rsync程式,就會導致負載過高,甚至有些伺服器會掛掉。這時候我們用到了rsync的程式鎖,在目錄下生成一個rsync.lock檔案,當crontab執行時,rsync會判斷鎖檔案是否存在,如果存在說明本次同步未完成,則不執行rsync。
資料一定要閉環
別人的介面抖動以及返回資料的異常,影響到前端展示對我們來說說是不能容忍的,這就需要我們針對各種情況一一校驗。
CMS總結
目前通過CMS搭建、正在搭建以及使用CMS API支援的PC端、移動端頁面約有上千個,這對CMS來說意義重大,隨著業務需求量的越來越大,也給我們帶來了新的期望。接下來,我們會從視覺化編輯、資料統計分析、關鍵詞管理、商品下架預警等方面進行相關的優化工作。
相關閱讀:
2016年8月12日-13日,由CSDN重磅打造的網際網路應用架構實戰峰會、運維技術與實戰峰會將在成都舉行,目前18位講師和議題已全部確認。兩場峰會大牛講師來自阿里、騰訊、百度、京東、小米、樂視、聚美優品、YY互娛、華為、360等知名網際網路公司,一線深度的實踐,共同探討高可用/高併發/高效能系統架構設計、電商架構、分散式架構、運維工具研發與實踐、運維自動化系統的構建、DevOps、雲上的運維案例分析、虛擬化技術、應用效能檢測與管理、遊戲行業的運維實踐等,將和與會嘉賓共同探討「構建更安全、更高效能、更穩定的架構和運維體系」等領域的話題與技術。【八折優惠中,點選這裡搶票,欲購從速。】
相關文章
- Django+Vue.js搭建前後端分離專案 web前後端分離專案實踐DjangoVue.js後端Web
- 前後端不分離到分離演變,優勢,前後端介面聯調,排錯及優化後端優化
- 零基礎搭建前後端分離專案後端
- 再談前後端分離後端
- 前後端分離那些事後端
- 淺談前後端分離後端
- 前後端分離——使用OSS後端
- SPA單頁面應用、前後端分離專案SEO優化的方法後端優化
- 前後端頁面分離導致session無法正常獲取的問題後端Session
- 前後端分離後的前端時代後端前端
- 前後端分離後模組開發後端
- 從零開始搭建前後端分離論壇 一後端
- SpringBoot+Vue前後端分離系統搭建Spring BootVue後端
- ???前後端分離模式的思考???後端模式
- 前後端分離——資料mock後端Mock
- vue前後端分離修改webpackVue後端Web
- 前後端分離整合SpringSecurity後端SpringGse
- 前後端分離,最佳實踐後端
- 淺談WEB前後端分離Web後端
- 什麼是前後端分離?後端
- 前後端分離實踐有感後端
- 從MVC到前後端分離MVC後端
- 前後端分離Ajax入門後端
- Flask前後端分離專案案例Flask後端
- 從部署上做到前後端分離後端
- 前後端分離的優缺點後端
- 實現前後端分離的心得後端
- 簡單的前後端分離 Cas後端
- Laravel 前後端分離 csrf 防護Laravel後端
- 實踐中的前後端分離後端
- 前後端分離之Ajax入門後端
- Cloudera Manager 前後端分離部署方法Cloud後端
- 《從零構建前後分離web專案》:開篇 - 縱觀WEB歷史演變Web
- 前後端分離開發腳手架後端
- jQuery 前後端分離專案總結jQuery後端
- 用jQuery怎麼做到前後端分離jQuery後端
- node-vue前後端分離記錄Vue後端
- 前後端分離開發部署模式【轉】後端模式