當前位置:
首頁 > 知識 > Golang在京東列表頁實踐總結

Golang在京東列表頁實踐總結

作者:張洪濤


原文:http://studygolang.com/articles/4744


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


目前線上狀態


基於搜索實現;

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


介面響應時間長,影響了用戶體驗;


沒法針對數據做二次優化;


轉化率相對較低;


基於以上原因,需要做出改變,所以就需要對老進行重構,如下


重構版本


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


要求時時過濾計算,介面相應時間要快,保證用戶體驗;


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


為何選擇golang

golang語言強大的並發能力;


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


基於以上兩點,所以選擇了golang語言作為服務端計算使用的語言。


重構後的架構圖

Golang在京東列表頁實踐總結



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


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


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


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

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


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


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


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


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

Golang在京東列表頁實踐總結



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


內存計算模型圖

Golang在京東列表頁實踐總結


簡單介紹下計算過程:


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


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


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


計算完成後會拿到當前頁面需要的產品ids;


然後通過id列表獲取到產品的詳細信息,並對產品屬性過過濾;


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


內存計算數據結構


如下圖所示:

Golang在京東列表頁實踐總結



以上結構是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 技術棧選擇


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


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


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


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序源 的精彩文章:

黑客是如何發現女朋友出軌的?
Linux 文件管理
Linux 下網路協議分析器 Wireshark 使用基礎

TAG:程序源 |

您可能感興趣

Google SRE最佳實踐之On-Call
vue Router在新標籤打開頁面的實踐
Spring Cloud Contract 在永輝雲創的研發實踐
華為在OpenStack Days China上分享混合雲行業場景及優秀實踐
Georgia Tech-真正的理論與實踐結合
技術解析系列PouchContainer Goroutine Leak 檢測實踐
第55期:Python機器學習實踐指南、Tensorflow 實戰Google深度學習框架
實踐秘籍:Boosting 與 AdaBoost
GemFire與Greenplum的最佳集成實踐之實施經驗談
Epic Games發布《虛擬製片實踐指南》
從選擇到實踐——It』s now or never
Apache Storm流計算模型 及WordCount源碼實踐
打包優化實踐(如何Code Spliting)
Uber Hadoop 文件系統最佳實踐
TalkingData的Spark On Kubernetes實踐
傳統數倉從 Teradata 遷移到 Hadoop平台實踐
Github 代碼實踐:Pytorch 實現的語義分割器
Github代碼實踐:Pytorch實現的語義分割器
BGP Confederation原理實踐
Istio技術與實踐02:源碼解析之Istio on Kubernetes 統一服務發現