2017京東商城-京麥平臺(tái)618備戰(zhàn)實(shí)踐

作為技術(shù)研發(fā)人員,我們常戲稱(chēng)京東每年只干兩件事,一個(gè)是618,另外一個(gè)是雙11.確實(shí)每一次的大促都是一場(chǎng)全兵演練,技術(shù)人員在這場(chǎng)戰(zhàn)斗中,從團(tuán)隊(duì)合作、技術(shù)提升、用戶(hù)意識(shí)上都有一個(gè)立體的提高。實(shí)難想象還有比這樣規(guī)模的促銷(xiāo)再有更好的鍛煉方式。

京麥平臺(tái)是目前京東所有商家唯一使用的一站式店鋪運(yùn)營(yíng)管理平臺(tái),商家借助京麥可以實(shí)現(xiàn)商品發(fā)布、打印訂單、出庫(kù)、訂單消息接收等等一系列的日常工作,京麥平臺(tái)更是集合了眾多ISV廠商為商家提供了更加豐富的功能,更好的賦能于商家。京麥平臺(tái)的技術(shù)架構(gòu)也在隨著京東業(yè)務(wù)的飛速發(fā)展不斷演化著。從早期的簡(jiǎn)單nginx+tomcat部署,到現(xiàn)在功能服務(wù)模塊化,獨(dú)立部署,享受著微服務(wù)帶來(lái)的便利,但同時(shí)也給我們大促的備戰(zhàn)帶來(lái)了幾多挑戰(zhàn)。

首先確定自己的備戰(zhàn)思路,梳理核心流程、找出薄弱點(diǎn),對(duì)薄弱點(diǎn)具體優(yōu)化,同時(shí)協(xié)調(diào)壓測(cè)對(duì)優(yōu)化結(jié)果驗(yàn)證,優(yōu)化和壓測(cè)會(huì)有一個(gè)反復(fù)的過(guò)程,后面我們還要實(shí)際演練,比如降級(jí)開(kāi)關(guān),防止實(shí)際情況發(fā)生的時(shí)候準(zhǔn)備好的功能不可用,最后我們要做一輪培訓(xùn),在工具使用,快速定位問(wèn)題,歷來(lái)的教訓(xùn)總結(jié)都過(guò)一遍,從心理層面上我們也要輔導(dǎo),大促期間發(fā)生的問(wèn)題都不是小問(wèn)題,研發(fā)人員在這種壓力下處理問(wèn)題有時(shí)候會(huì)變形,我們會(huì)在這方面做一次心理疏解。這中間我們可以利用幾個(gè)規(guī)則,二八法則,找出20%重要核心的功能,比如京麥的登錄、交易、價(jià)格門(mén)消息推送。在找薄弱點(diǎn)的時(shí)候我們可以試試墨菲定律的幾點(diǎn)規(guī)則,“可能出錯(cuò)的事總會(huì)出錯(cuò)”,“如果你擔(dān)心某種情況發(fā)生,那么他就有可能發(fā)生”,最后我們還會(huì)找大家一起列出你心中最不可能出現(xiàn)問(wèn)題的系統(tǒng)和功能點(diǎn),那么列出來(lái)重點(diǎn)對(duì)待,沒(méi)錯(cuò),是重點(diǎn)對(duì)待。

我們常用的備戰(zhàn)技術(shù),肯定不是重啟,回滾,加機(jī)器,^_^。這里面?zhèn)€人總結(jié)有分離技術(shù),緩存技術(shù),SQL優(yōu)化,快速失敗,降級(jí)限流。我們來(lái)逐一介紹。

分離技術(shù):

話說(shuō)“天下大事,合久必分,分久必合”,但在軟件架構(gòu)領(lǐng)域,一直是一個(gè)分的趨勢(shì),比如京麥平臺(tái)有提供ISV的服務(wù)、提供京麥自有客戶(hù)端的服務(wù)、提供其他平臺(tái)的服務(wù),同時(shí)還有監(jiān)控服務(wù),日志服務(wù),消息服務(wù)等,需要將業(yè)務(wù)服務(wù)隔離部署,線下分析和線上運(yùn)行隔離,同時(shí)還可以采取線程隔離,比如JSF里面為每個(gè)不同重要的服務(wù)分別一個(gè)線程組的方式。數(shù)據(jù)庫(kù)層面上主從分離,京麥平臺(tái)的業(yè)務(wù)都是讀多寫(xiě)少,可以充分利用分庫(kù)的資源。還可以再將數(shù)據(jù)庫(kù)細(xì)分,按照主要業(yè)務(wù)拆分不同的數(shù)據(jù)庫(kù),結(jié)合RPC使用,更大降低數(shù)據(jù)庫(kù)層面的耦合程度。

緩存技術(shù):

如果軟件里面真的有一種銀彈的話,我認(rèn)為就是緩存,當(dāng)你性能優(yōu)化遇到瓶頸的時(shí)候,當(dāng)你想抗量的時(shí)候,你都會(huì)想到緩存。這里有一個(gè)鐵律,那就是,對(duì)外暴露的接口一定不能直達(dá)數(shù)據(jù)庫(kù)。我們常用的緩存是redis+jvmcache。計(jì)算redis穿透率的時(shí)候我們可以,通過(guò)UMP來(lái)實(shí)現(xiàn),在一個(gè)方法的總?cè)肟诼顸c(diǎn),比如統(tǒng)計(jì)出1分鐘調(diào)用M次,在請(qǐng)求redis的入口埋點(diǎn),統(tǒng)計(jì)出1分鐘調(diào)用N次,計(jì)算命中率:N/M.。在使用redis的時(shí)候要注意含有大數(shù)值的key,常常量一上來(lái)會(huì)造成redis集群的熱點(diǎn)訪問(wèn),直接將單一節(jié)點(diǎn)打死。這樣的情況下我們就要拆分這樣的大key。同時(shí)將緩存DB化,就是不設(shè)置超時(shí)時(shí)間,這樣全部用redis來(lái)抗量。本地緩存這塊我們常用的有Guava-cache,通過(guò)本地緩存我們可以做三級(jí)防護(hù),或者做托底數(shù)據(jù)等。如果數(shù)據(jù)“尺寸較小”、“高頻的讀取操作”、“變更操作較少”使用這種嵌入式緩存將非常合適。

SQL優(yōu)化:

每次大促前我們都要將系統(tǒng)中性能慢的sql抓出來(lái),而且這種工作投入產(chǎn)出比極高,也就是可以花費(fèi)較小代價(jià)帶來(lái)極大的性能收益。sql性能問(wèn)題,大多數(shù)情況下是沒(méi)有索引引起的,這可能是后續(xù)業(yè)務(wù)變化迅速,上線前代碼review的遺漏,需要這個(gè)時(shí)候統(tǒng)一過(guò)一遍。還有就是索引使用錯(cuò)誤,比如索引字段是字符串類(lèi)型,但是程序中請(qǐng)求DB的時(shí)候傳的是long類(lèi)型,索引失效,表中數(shù)量過(guò)多,做了一次全表掃描,性能會(huì)很差。還有時(shí)候我們添加索引的時(shí)候要看區(qū)分度,計(jì)算索引區(qū)分度的方法,不重復(fù)的索引值/總記錄數(shù),值越接近1,說(shuō)明區(qū)分度越高,查詢(xún)的時(shí)候mysql就會(huì)過(guò)濾掉更多的行數(shù)據(jù)。還有,添加索引最好結(jié)合mysql執(zhí)行計(jì)劃來(lái)判斷。有時(shí)候做了過(guò)多的join操作,比如超過(guò)3張表以上,我們就要想著去拆解這些sql語(yǔ)句。在就是數(shù)據(jù)庫(kù)層面我可以把歷史數(shù)據(jù)轉(zhuǎn)出減少數(shù)據(jù)量來(lái)達(dá)到提高查詢(xún)速度的目的。

快速失?。?/b>

快速失敗策略實(shí)際上是一種自我保護(hù)措施,比如調(diào)用第三方接口超時(shí),如果超時(shí)時(shí)間設(shè)置過(guò)長(zhǎng),訪問(wèn)量大的時(shí)候,就會(huì)導(dǎo)致請(qǐng)求線程積壓,如果此時(shí)有線程隔離還好,若剛好沒(méi)有,那么訪問(wèn)量一上來(lái)就會(huì)迅速導(dǎo)致cpu飆高。京麥平臺(tái)的特點(diǎn)之一,會(huì)大量調(diào)用第三方接口服務(wù),我們會(huì)對(duì)每個(gè)方法動(dòng)態(tài)的設(shè)置超時(shí)時(shí)間,如果UMP報(bào)警再結(jié)合JVM性能數(shù)據(jù),我們會(huì)將這個(gè)接口的超時(shí)時(shí)間閾值調(diào)小。通過(guò)zookeeper下發(fā)到每一個(gè)服務(wù)節(jié)點(diǎn)上。在大促前,我們會(huì)重點(diǎn)檢查mysql、redis、jsf等rpc調(diào)用的超時(shí)設(shè)置,確保每一次rpc調(diào)用都要有上限閾值。關(guān)于RPC調(diào)用超時(shí),這里多說(shuō)一下,有時(shí)候我們會(huì)發(fā)現(xiàn)調(diào)用端性能比如超過(guò)500ms,但是服務(wù)端確是在100ms上線徘徊。這里面我們除了檢查網(wǎng)關(guān)延時(shí),tcp重傳,還要注意一點(diǎn),就是任何一個(gè)成熟的rpc框架都不會(huì)讓業(yè)務(wù)線程直接參與網(wǎng)絡(luò)請(qǐng)求,rpc會(huì)提供一個(gè)消息隊(duì)列,調(diào)用端直接跟消息隊(duì)列打交道。此時(shí),我們就要想到隊(duì)列這塊是否有問(wèn)題了。

降級(jí)限流:

這種技術(shù)實(shí)際上是保命的措施。降級(jí)一般有屛蔽降級(jí)和容錯(cuò)降級(jí)兩種,對(duì)一些非核心的功能,比如京麥的麥圈,服務(wù)號(hào),論壇等功能,而他們恰恰又請(qǐng)求著mysql,redis等公共資源,為了減少這種競(jìng)爭(zhēng)我們就會(huì)對(duì)這些功能進(jìn)行屛蔽降級(jí),直接切斷RPC調(diào)用,不再發(fā)起遠(yuǎn)程調(diào)用,返回空或者其它異常提示,減少公共資源的訪問(wèn)。容錯(cuò)降級(jí),是一種放通,則不顯得像屛蔽降級(jí)那樣暴力,往往會(huì)有托底措施保證用戶(hù)更好的體驗(yàn),托底措施比如我們常用的本地緩存數(shù)據(jù)等。再說(shuō)下降級(jí)開(kāi)關(guān),目前京麥?zhǔn)遣捎媒y(tǒng)一配置中心來(lái)使用。同樣,限流技術(shù)在京麥平臺(tái)中也是異常重要的一個(gè)措施,尤其是對(duì)京麥網(wǎng)關(guān)的調(diào)用。我們目前是采用令牌桶的方法,實(shí)現(xiàn)方式是Guava RateLimter,簡(jiǎn)單有效,再結(jié)合統(tǒng)一配置中心,我們可以動(dòng)態(tài)調(diào)整限流閾值。不用重啟服務(wù)器即可實(shí)現(xiàn)快速限流策略調(diào)整。我們?cè)诰W(wǎng)關(guān)里面還有一個(gè)設(shè)置,就是并發(fā)度,這個(gè)是方法粒度的,對(duì)每一個(gè)調(diào)用第三方的接口都有一個(gè)并發(fā)度數(shù)值設(shè)置,而且是動(dòng)態(tài)設(shè)置,也是通過(guò)zookeeper下發(fā)到每一個(gè)服務(wù)節(jié)點(diǎn)上。并發(fā)度的具體實(shí)現(xiàn)是通過(guò)jdk的Semaphore。

我們?cè)賮?lái)說(shuō)一下,監(jiān)控配置和性能壓測(cè)。

監(jiān)控配置是一定不能缺少,我們要求自己一定要第一時(shí)間早于用戶(hù)發(fā)現(xiàn)問(wèn)題。平時(shí)開(kāi)發(fā)在上線的時(shí)候我們都應(yīng)該有統(tǒng)一要求每一個(gè)RPC調(diào)用都要有監(jiān)控和錯(cuò)誤棧的輸出。在備戰(zhàn)期間實(shí)際是對(duì)監(jiān)控配置的一個(gè)治理過(guò)程,監(jiān)控配置key要規(guī)則化,比如***.mysql.***,***.redis.***等讓我們一眼便知到是操作的哪一個(gè)資源。京麥平臺(tái)這次備戰(zhàn)的過(guò)程中通過(guò)采用AOP的方式,把所有類(lèi)似的調(diào)用統(tǒng)一規(guī)范化處理,后續(xù)結(jié)合Python腳本對(duì)監(jiān)控閾值進(jìn)行統(tǒng)一調(diào)整。這樣走下來(lái)一方面把我們平時(shí)可能漏掉的監(jiān)控給補(bǔ)全,另外一方面我們的監(jiān)控配置按照統(tǒng)一的規(guī)則來(lái)生成。

性能壓測(cè)這一塊,可以很好的檢驗(yàn)我們優(yōu)化的結(jié)果,壓測(cè)的過(guò)程中我們關(guān)注qps的同時(shí),還要結(jié)合服務(wù)器的cpu、io、內(nèi)存等機(jī)器性能指標(biāo)來(lái)定位我們的性能瓶頸。最后來(lái)預(yù)估我們系統(tǒng)的承載能力,提供數(shù)據(jù)支撐來(lái)申請(qǐng)服務(wù)器或者docker資源。壓測(cè)工具研發(fā)可以自己寫(xiě)腳本,借助jmeter、loadrunner等工具,也可以有計(jì)劃的聯(lián)系性能壓測(cè)組他們協(xié)助執(zhí)行。最困難的還是產(chǎn)生真實(shí)的壓力。

還有一個(gè)備戰(zhàn)點(diǎn),返璞歸真,回到代碼,重點(diǎn)核心功能檢查一遍,把壞味道的代碼查出來(lái)。比如join了很多張表的sql語(yǔ)句,日志輸出沒(méi)有采用條件方式或者占位符的方式,日志重復(fù)打印,try代碼塊放到了事務(wù)中,循環(huán)體中含有低性能的語(yǔ)句,鎖代碼塊中進(jìn)行RPC調(diào)用,等等。

最后,我們可以想一下備戰(zhàn)備的是什么,總結(jié)歷次的大促,我認(rèn)為主要在,工具、知識(shí)、經(jīng)驗(yàn)三個(gè)方面的備戰(zhàn)。工欲善其事,必先利其器,我們要有一些個(gè)好的工具輔助我們解決問(wèn)題,比如MDC(里面含有CPU,網(wǎng)絡(luò)等監(jiān)控)、UMP(京東自研方法性能,可用率等監(jiān)控平臺(tái))、CAP(容器的總體監(jiān)控,也含有cpu負(fù)載等信息查看)。知識(shí)層面,是我們歷來(lái)的積累,我們的認(rèn)識(shí)的提高,使用工具時(shí)候的指導(dǎo)。經(jīng)驗(yàn)是我們以往的大大小小的教訓(xùn)的總結(jié),前車(chē)之鑒,防止我們?cè)俅伟l(fā)生類(lèi)似的事情。

以“結(jié)硬寨,打呆賬”這句話結(jié)束此次618備戰(zhàn)的總結(jié),最重要的一點(diǎn),還是要求我們備戰(zhàn)在平時(shí)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容