Golang在京東列表頁實踐總結

Golang在京東列表頁實踐總結php

做者:張洪濤git

 

10餘年軟件開發和設計經驗,曾就任於搜狐、搜狗、前matrixjoy公司聯合創始人、甘普科技CTO。github

 

目前線上狀態golang

 

  • 基於搜索實現;web

  • 全量數據,搜索結果不理想;redis

  • 接口響應時間長,影響了用戶體驗;json

  • 無法針對數據作二次優化;數據結構

  • 轉化率相對較低;架構

 

基於以上緣由,須要作出改變,因此就須要對老進行重構,以下併發

 

重構版本

 

  • 非全量數據,線下異步根據數據模型進行進行篩選部分最優數據;

  • 要求時時過濾計算,接口相應時間要快,保證用戶體驗

  • 數據進行優化,提升轉換率,提搞GMV;

 

爲什麼選擇golang

 

  • golang語言強大的併發能力;

  • 與C相媲美的性能,新版對cpu計算要求較高;

 

基於以上兩點,因此選擇了golang語言做爲服務端計算使用的語言。

 

重構後的架構圖

 

解釋下架構圖各個模塊功能

 

  1. Nginx+Lua: 用來渲染頁面,拿到go計算服務的json數據渲染到頁面端,最終呈現給終端用戶;

  2. Config Center 是用來協調worker、lua服務以及go計算服務的控制中心;

  3. Score Worker、Data Worker 是一個用來線下異步計算數據的2個worker,從數據平臺拿到數據加上各類數據模型計算最優數據,計算完成後會通知 Config Center,同時數據會進入DB,進行持久化;

  4. 深 黃色部分是go計算服務,只要分2個集羣,一個線上集羣、一個線下集羣,異步計算服務根據配置中心選擇一個線下集羣進行數據計算,計算完成後會通知 Config Center,而後相應的線下集羣會進行數據預加載到分片的redis以及go計算服務的各個節點中,而後線下集羣準備就緒,能夠隨時切到線上提供服務;

  5. MQ Worker是一個處理消息的服務,主要包括sku上架、下架、庫存變更、以及價格變更等消息;

  6. Msg Receiver 接受到MQ worker的消息後進行消息處理,而後發送的go計算服務的各個節點中;

 

線上部署的多個機房,避免單機房故障;

 

 

數據處理流程以下圖所示:

 

上圖是一個完整的數據處理流程,整個流程中最核心的部分是架構圖中的Config Center,數據流程中的每一步操做都依賴於配置中心。因此整個架構中配置中心很是重要。

 

 

內存計算模型圖

 

簡單介紹下計算過程:

  1. 解析頁面傳過來的參數,整理成相應的結構體;

  2. 格式化的結構體,好比品牌、價格、sku屬性、庫存、產品標籤、排序類型等;

  3. 經過格式化的結構體進行內存中計算,包括過濾、排序等計算操做;

  4. 計算完成後會拿到當前頁面須要的產品ids

  5. 而後經過id列表獲取到產品的詳細信息,並對產品屬性過過濾;

  6. 最終把結構化的json數據返回給lua,進行頁面渲染;

 

內存計算數據結構

 

以下圖所示:

以 上結構是go的一個結構體,包括了頁面上全部要進行計算的屬性,後續全部的內存中計算過濾、排序都是基於此結構體進行,每一個商品對應一個相應的結構體,每 個分類大約有幾萬個商品,內存中也有對應的結構體。這些結構體是在數據異構完成後,數據預先加載內存,避免在提供服務的時候再去初始化。

 

開發過程當中遇到的問題

 

遇到2個比較嚴重的問題:

  • Golang自身序列化性能低下

  • GolangGC困擾

 

針對第一個序列化、反序列化問題,咱們嘗試過golang內置的encoding/json、encoding/gob兩種方式,可是效果都特別不理想,耗費cpu過多,qps 一直上不去。

後來請教beego做者的謝大同窗,給推薦了ffjson,也親自寫了一些測試ffjson的代碼,最終ffson以3倍優點完勝golang內置json序列化,因此最後採用了ffjson。

第二個問題,golang GC問題,相信很多同窗在開發的過程當中也遇到過這個問題,其實咱們認真分析,發現GC時候很大部分時間是浪費的Marking階段,因此咱們能夠從如下幾個點優化咱們的代碼:

減小內存中對象數量

儘可能重複內存申請,採用對象池,避免重複申請、釋放內存,能夠很是有效的減小GC;

開啓GODEBUG=gctrace=1,能夠很是清晰的看到內存中對象數量、內存使用狀況。以及各個階段的時間開銷;

另外可使用golang內置的性能監控工具pprof包,能夠方便得監控到內存、cpu的是使用狀況。

 

Go 技術棧選擇

 

  1. web 框架,採用Asta的beego(http://beego.me)裏邊的orm部分寫的很贊,建議你們仔細讀讀裏邊的源碼,對lua部分的API設計都 是採用beego現成的MVC設計,能夠方便得定義接口,並在路由中配置便可提供服務;具體github地址:http://github.com /astaxie/beego

  2. json序列化,https://github.com/pquerna/ffjson,裏邊有詳細的使用說明文檔;

  3. redis:http://github.com/go-redis/redis 在這之上咱們內部又對主從操做封裝了一層;

 

轉載自:http://studygolang.com/articles/4744

相關文章
相關標籤/搜索