小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

每秒訂單數(shù)25倍提升,蘑菇街怎樣跨過海量服務(wù)架構(gòu)的技術(shù)藩籬?

 melon1024 2016-09-29
本文根據(jù)白輝在2016ArchSummit全球架構(gòu)師(深圳)峰會上的演講整理而成。ArchSummit北京站即將在12月2日開幕,更多專題講師信息請到北京站官網(wǎng)查詢(http://bj2016./)。

本文主要結(jié)構(gòu)如下,讀完大概需要 12 分鐘。

  • 電商系統(tǒng)發(fā)展中期面臨的一般性問題

  • 系統(tǒng)拆分與服務(wù)化過程

  • 購買鏈路的性能提升

  • 購買鏈路的穩(wěn)定性提升

  • 總結(jié)及下一步展望

老司機簡介

白輝,人稱七公,2014年以前在阿里巴巴B2B主要負責(zé)Aliexpress資金中心、評價、任務(wù)中心等系統(tǒng)。14年8月離開阿里出國游歷,15年回國后加入蘑菇街,目前在蘑菇街、美麗說、淘世界大集團共享的電商基礎(chǔ)平臺負責(zé)購物車下單小組及交易平臺架構(gòu)工作。

1

電商系統(tǒng)發(fā)展中期面臨的一般性問題

我總結(jié)了一下,一般電商系統(tǒng)發(fā)展到中期都會面臨三個方面的問題(如圖)。

第一方面是業(yè)務(wù)問題。比如,一開始做業(yè)務(wù)的時候可能很隨意,一是并不考慮業(yè)務(wù)模型、系統(tǒng)架構(gòu),二是業(yè)務(wù)之間的耦合比較嚴(yán)重,比如交易和資金業(yè)務(wù),有可能資金和外部第三方支付公司的交互狀態(tài)耦合在交易系統(tǒng)里,這些非常不利于業(yè)務(wù)發(fā)展。

第二方面是系統(tǒng)問題。2014年我們面臨單體應(yīng)用,400人開發(fā)一個大應(yīng)用,擴展性很差,業(yè)務(wù)比較難做。

第三方面是支撐問題,比如關(guān)于環(huán)境、開發(fā)框架和質(zhì)量工具等。這些是電商系統(tǒng)發(fā)展到中期都會面臨的問題,中期的概念是用戶過了千萬,PV過了1億。

我們來看一下蘑菇街2015年初面臨的問題。蘑菇街2015年用戶過億,PV過10億,業(yè)務(wù)在超高速發(fā)展,每年保持3倍以上的增長。電商促銷、交易、支付等業(yè)務(wù)形態(tài)都在快速膨脹,我們需要快速支持業(yè)務(wù)發(fā)展,而不是成為業(yè)務(wù)的瓶頸。那么就是要去做系統(tǒng)的拆分和服務(wù)化。

2

系統(tǒng)拆分與服務(wù)化過程

第二部分的內(nèi)容,是關(guān)于蘑菇街系統(tǒng)拆分與服務(wù)化的歷程。

按照如下幾條思路(見上圖),我們進行系統(tǒng)拆分以及服務(wù)化。最開始,大家在同一個應(yīng)用里開發(fā)一些業(yè)務(wù)功能,都是選擇速度最快的方式,所有的DB和業(yè)務(wù)代碼都是在一起的。首先我們將DB做垂直拆分。

第二步是做業(yè)務(wù)系統(tǒng)垂直拆分,包括交易、資金等。

第三步是在系統(tǒng)拆完了之后要考慮提供什么樣的API來滿足業(yè)務(wù)的需求?這里我們要做數(shù)據(jù)建模 業(yè)務(wù)建模,數(shù)據(jù)建模方面包括數(shù)據(jù)表的設(shè)計和擴展支持,數(shù)據(jù)模型應(yīng)該非常穩(wěn)定;業(yè)務(wù)建模方面,使用標(biāo)準(zhǔn)和靈活的API,而且盡量不用修改代碼或者改少量代碼就能支持業(yè)務(wù)需求。

第四步是需要將業(yè)務(wù)邏輯下沉到服務(wù),Web層專注于展示邏輯和編排,不要涉及過多業(yè)務(wù)的事情。然后用SOA中間件建設(shè)服務(wù)化系統(tǒng)。最后會做一些服務(wù)的治理。

來看一個API服務(wù)化的例子,在做服務(wù)化之前和做服務(wù)化之后,交易創(chuàng)建下單業(yè)務(wù)有什么不一樣。服務(wù)化之前我們面臨的問題有:入口分散,如果要在底層做任何一個微小的改動,十幾個入口需要幾十個人配合修改,這是非常不合理的一種方式;多端維護多套接口,成本非常高;還有穩(wěn)定性的問題,依賴非常復(fù)雜,維護很難。

我剛到蘑菇街的時候,一次大促活動就導(dǎo)致數(shù)據(jù)庫崩潰,暴露了系統(tǒng)架構(gòu)很大的問題和總量上的瓶頸。按照上面提到幾條思路去做服務(wù)化,看看有了哪些改善?首先是API統(tǒng)一,多個端、多個業(yè)務(wù)都用統(tǒng)一的API提供;其次是依賴有效管理起來,大事務(wù)拆分成多個本地小事務(wù);最后降低了鏈路風(fēng)險,邏輯更加清晰,穩(wěn)定性更好。

2015年3月我來到蘑菇街之后,先制訂了服務(wù)化的規(guī)范,探討了到底什么是標(biāo)準(zhǔn)的服務(wù)化。在做服務(wù)化的過程中,發(fā)現(xiàn)大家代碼風(fēng)格完全不一樣,所以制定編碼規(guī)范非常重要。

2015年8月,我們完成了各個模塊的改造,包括用戶、商品、交易、訂單、促銷、退款等,然后有了服務(wù)化架構(gòu)1.0的體系。在此基礎(chǔ)之上,我們進一步做了提升流量和穩(wěn)定性等更深度的建設(shè)。2015年9月,我們實施了分庫分表和鏈路性能提升優(yōu)化,2015年10月做了服務(wù)治理和服務(wù)保障。

接下來,以服務(wù)架構(gòu)和服務(wù)體系建設(shè)為主線,講一下去年整個網(wǎng)站架構(gòu)升級的過程。

在服務(wù)化1.0體系完成之后,我們得到了一個簡單的體系,包含下單服務(wù)、營銷服務(wù)、店鋪服務(wù)、商品服務(wù)和用戶服務(wù),還有簡單的RPC框架Tesla。當(dāng)時,我們并沒有做很多性能優(yōu)化的事情,但是通過業(yè)務(wù)流程化簡和邏輯優(yōu)化,每秒最大訂單數(shù)從400提升到1K,基礎(chǔ)服務(wù)也都搭建了起來。

有了1.0初步的服務(wù)化體系之后,更進一步,我們一是要繼續(xù)深入網(wǎng)站如資金等的服務(wù)化,二是要做服務(wù)內(nèi)部的建設(shè),比如容量、性能,這也是接下來要講的內(nèi)容。

3

購買鏈路的性能提升

這個鏈路(見圖)是比較典型的電商鏈路,有商品頁、下單、支付、營銷和庫存等內(nèi)容。一開始每個點都有瓶頸,每個瓶頸都是一個籬笆,我們要正視它,然后翻越它。

我們先來看第一個籬笆墻:下單的瓶頸。

2015年“3.21”大促的時候,DB崩潰了,這個瓶頸很難突破。下一個訂單要插入很多條數(shù)據(jù)記錄到單DB的DB表。我們已經(jīng)用了最好的硬件,但是瓶頸依然存在,最主要的問題就是DB單點,需要去掉單點,做成可水平擴展的。

流量上來了,到DB的行寫入數(shù)是2萬/秒,對DB的壓力很大。寫應(yīng)該控制在一個合理的量,DB負載維持在較低水平,主從延時也才會在可控范圍內(nèi)。所以DB單點的問題非常凸顯,這座大山必須邁過去,我們做了一個分庫分表組件TSharding來實施分庫分表。

將我們寫的分庫分表工具與業(yè)界方案對比,業(yè)界有淘寶TDDL Smart Client的方式,還有Google的Vitess等的Proxy方式,這兩種成熟方案研發(fā)和運維的成本都太高,短期內(nèi)我們接受不了,所以借鑒了Mybatis Plugin的方式,但Mybatis Plugin不支持數(shù)據(jù)源管理,也不支持事務(wù)。

我大概花了一周時間寫了一個組件——自研分庫分表組件TSharding(https://github.com/baihui212/tsharding),然后快速做出方案,把這個組件應(yīng)用到交易的數(shù)據(jù)庫,在服務(wù)層和DAO層,訂單容量擴展到千億量級,并且可以繼續(xù)水平擴展。TSharding上線一年之后,我們將其開放出來。

第二個籬笆墻就是營銷服務(wù)RT的問題。促銷方式非常多,包括各種紅包、滿減、打折、優(yōu)惠券等。實際上促銷的接口邏輯非常復(fù)雜,在“雙11”備戰(zhàn)的時候,面對這個復(fù)雜的接口,每輪鏈路壓測促銷服務(wù)都會發(fā)現(xiàn)問題,之后優(yōu)化再壓測,又發(fā)現(xiàn)新的問題。

我們來一起看看遇到的各種問題以及是如何解決的。首先是壓測出現(xiàn)接口嚴(yán)重不可用,這里可以看到DB查詢頻次高,響應(yīng)很慢,流量一上來,這個接口就崩潰了。那怎么去排查原因和解決呢?

首先是SQL優(yōu)化,用工具識別慢SQL,即全鏈路跟蹤系統(tǒng)Lurker。

這張圖我簡單介紹一下。遇到SQL執(zhí)行效率問題的時候,就看是不是執(zhí)行到最高效的索引,掃表行數(shù)是不是很大,是不是有filesort。有ORDER BY的時候,如果要排序的數(shù)據(jù)量不大或者已經(jīng)有索引可以走到,在數(shù)據(jù)庫的內(nèi)存排序緩存區(qū)一次就可以排序完。

如果一次不能排序完,那就先拿到1000個做排序,然后輸出到文件,然后再對下1000個做排序,最后再歸并起來,這就是filesort的大致過程,效率比較低。所以盡量要走上索引,一般類的查詢降低到2毫秒左右可以返回。

其次是要讀取很多優(yōu)惠規(guī)則和很多優(yōu)惠券,數(shù)據(jù)量大的時候DB是很難扛的,這時候我們要做緩存和一些預(yù)處理。特別是查詢DB的效率不是很高的時候,盡量緩存可以緩存的數(shù)據(jù)、盡量緩存多一些數(shù)據(jù)。但如果做緩存,DB和緩存數(shù)據(jù)的一致性是一個問題。

在做數(shù)據(jù)查詢時,首先要看本地緩存有沒有開啟,如果本地緩存沒有打開,就去查分布式緩存,如果分布式緩存中沒有就去查DB,然后從DB獲取數(shù)據(jù)過來。需要盡量保持DB、緩存數(shù)據(jù)的一致性,如果DB有變化,可以異步地做緩存數(shù)據(jù)失效處理,數(shù)據(jù)百毫秒內(nèi)就失效掉,減少不一致的問題。

另外,如果讀到本地緩存,這個內(nèi)存訪問比走網(wǎng)絡(luò)請求性能直接提升了一個量級,但是帶來的弊端也很大,因為本地緩存沒有辦法及時更新,平時也不能打開,因為會帶來不一致問題。

但大促高峰期間我們會關(guān)閉關(guān)鍵業(yè)務(wù)數(shù)據(jù)變更入口,開啟本地緩存,把本地緩存設(shè)置成一分鐘失效,一分鐘之內(nèi)是可以緩存的,也能容忍短暫的數(shù)據(jù)不一致,所以這也是一個很好的做法。

同樣的思路,我們也會把可能會用到的數(shù)據(jù)提前放到緩存里面,做預(yù)處理。在客戶端進行數(shù)據(jù)預(yù)處理,要么直接取本地數(shù)據(jù),或者在本地直接做計算,這樣更高效,避免了遠程的RPC。大促期間我們就把活動價格信息預(yù)先放到商品表中,這樣部分場景可以做本地計價,有效解決了計價接口性能的問題。

再就是讀容量問題,雖然緩存可以緩解壓力,但是DB還是會有幾十K的讀壓力,單點去扛也是不現(xiàn)實的,所以要把讀寫分離,如果從庫過多也有延時的風(fēng)險,我們會把數(shù)據(jù)庫的并行復(fù)制打開。

我們來看一下數(shù)據(jù)。這是去年“雙11”的情況(如圖)。促銷服務(wù)的RT得到了有效控制,所以去年“雙11”平穩(wěn)度過。

接下來講一個更基礎(chǔ)、更全局的優(yōu)化,就是異步化。比如說下單的流程,有很多業(yè)務(wù)是非實時性要求的,比如下單送優(yōu)惠券,如果在下單的時候同步做,時間非常長,風(fēng)險也更大,其實業(yè)務(wù)上是非實時性或者準(zhǔn)實時性的要求,可以做異步化處理,這樣可以減少下單對機器數(shù)量的要求。

另外是流量高峰期的一些熱點數(shù)據(jù)。大家可以想象一下,下單的時候,一萬個人競爭同一條庫存數(shù)據(jù),一萬個節(jié)點鎖在這個請求上,這是多么恐怖的事情。

所以我們會有異步隊列去削峰,先直接修改緩存中的庫存數(shù)目,改完之后能讀到最新的結(jié)果,但是不會直接競爭DB,這是異步隊列削峰很重要的作用。還有,數(shù)據(jù)庫的競爭非常厲害,我們需要把大事務(wù)做拆分,盡量讓本地事務(wù)足夠小,同時也要讓多個本地事務(wù)之間達到一致。

異步是最終達到一致的關(guān)鍵,異步的處理是非常復(fù)雜的??梢钥匆幌逻@個場景(見圖),這是一個1-6步的處理過程,如果拆分成步驟1、2、3、4、end,然后到5,可以異步地做;6也一樣,并且5和6可以并行執(zhí)行。同時,這個步驟走下來鏈路更短,保障也更容易;步驟5和6也可以單獨保障。所以異步化在蘑菇街被廣泛使用。

異步化之后面臨的困難也是很大的,會有分布式和一致性的問題。交易創(chuàng)建過程中,訂單、券和庫存要把狀態(tài)做到絕對一致。但下單的時候如果先鎖券,鎖券成功了再去減庫存,如果減庫存失敗了就是很麻煩的事情,因為優(yōu)化券服務(wù)在另外一個系統(tǒng)里,如果要同步調(diào)用做券的回滾,有可能這個回滾也會失敗,這個時候處理就會非常復(fù)雜。

我們的做法是,調(diào)用服務(wù)超時或者失敗的時候,我們就認為失敗了,就會異步發(fā)消息通知回滾。優(yōu)惠券服務(wù)和庫存服務(wù)被通知要做回滾時,會根據(jù)自身的狀態(tài)來判斷是否要回滾,如果鎖券成功了券就回滾,減庫存也成功了庫存做回滾;如果庫存沒有減就不用回滾。

所以我們是通過異步發(fā)消息的方式保持多個系統(tǒng)之間的一致性;如果不做異步就非常復(fù)雜,有的場景是前面所有的服務(wù)都調(diào)用成功,第N個服務(wù)調(diào)用失敗。另外的一致性保障策略包括Corgi MQ生產(chǎn)端發(fā)送失敗會自動重試保證發(fā)成功,消費端接收ACK機制保證最終的一致。另外,與分布式事務(wù)框架比起來,異步化方案消除了二階段提交等分布式事務(wù)框架的侵入性影響,降低了開發(fā)的成本和門檻。  

另一個場景是,服務(wù)調(diào)用上會有一些異步的處理。以購物車業(yè)務(wù)為例,購物車列表要調(diào)用10個Web服務(wù),每一個服務(wù)返回的時間都不一樣,比如第1個服務(wù)20毫秒返回,第10個服務(wù)40毫秒返回,串行執(zhí)行的效率很低。

而電商類的大多數(shù)業(yè)務(wù)都是IO密集型的,而且數(shù)據(jù)量大時還要分批查詢。所以我們要做服務(wù)的異步調(diào)用。比如下圖中這個場景,步驟3處理完了之后callback馬上會處理,步驟4處理完了callback也會馬上處理,步驟3和4并不相互依賴,且處理可以同時進行了,提高了業(yè)務(wù)邏輯執(zhí)行的并行度。

目前我們是通過JDK7的Future和Callback實現(xiàn)的,在逐步往JDK8的Completable Future遷移。這是異步化在網(wǎng)站整體的應(yīng)用場景,異步化已經(jīng)深入到我們網(wǎng)站的各個環(huán)節(jié)。

剛才我們講了鏈路容量的提升、促銷RT的優(yōu)化,又做了異步化的一些處理。那么優(yōu)化之后怎么驗證來優(yōu)化的效果呢?到底有沒有達到預(yù)期?我們有幾個壓測手段,如線下單機壓測識別應(yīng)用單機性能瓶頸,單鏈路壓測驗證集群水位及各層核?系統(tǒng)容量配比,還有全鏈路壓測等。

這是去年“雙11”之前做的壓測(見圖),達到了5K容量的要求。今年對每個點進一步深入優(yōu)化,2016年最大訂單提升到了10K,比之前提升了25倍。實際上這些優(yōu)化可以不斷深入,不僅可以不斷提高單機的性能和單機的QPS,還可以通過對服務(wù)整體上的優(yōu)化達到性能的極致,并且可以引入一些廉價的機器(如云主機)來支撐更大的量。

我們?yōu)槭裁匆鲞@些優(yōu)化?業(yè)務(wù)的發(fā)展會對業(yè)務(wù)系統(tǒng)、服務(wù)框架提出很多很高的要求。因此,我們對Tesla做了這些改善(見圖),服務(wù)的配置推送要更快、更可靠地到達客戶端,所以有了新的配置中心Metabase,也有了Lurker全鏈路監(jiān)控,服務(wù)和服務(wù)框架的不斷發(fā)展推動了網(wǎng)站其他基礎(chǔ)中間件產(chǎn)品的誕生和發(fā)展。2015年的下半年我們進行了一系列中間件的自研和全站落地。

我們得到了服務(wù)架構(gòu)1.5的體系(見圖),首先是用戶服務(wù)在最底層,用戶服務(wù)1200K的QPS,庫存250K,商品服務(wù)400K,營銷200K,等等。

接下來我們看一下這一階段,Tesla開始做服務(wù)管控,真正成為了一個服務(wù)框架。我們最開始做發(fā)布的時候,客戶端、服務(wù)端由于做的只是初級的RPC調(diào)用,如果服務(wù)端有變更,客戶端可能是幾秒甚至數(shù)十秒才能拉到新配置,導(dǎo)致經(jīng)常有客戶投訴。

有了對服務(wù)變更推送更高的要求后,我們就有了Matabase配置中心,服務(wù)端如果有發(fā)布或者某一刻崩潰了,客戶端馬上可以感知到,這樣就完成了整個服務(wù)框架連接優(yōu)化的改進,真正變成服務(wù)管控、服務(wù)治理框架的開端。

4

購買鏈路的穩(wěn)定性提升    

有了上面講到的服務(wù)化改進和性能提升之后,是不是大促的時候看一看監(jiān)控就行了?其實不是。大流量來的時候,萬一導(dǎo)致整個網(wǎng)站崩潰了,一分鐘、兩分鐘的損失是非常大的,所以還要保證服務(wù)是穩(wěn)的和高可用的。只有系統(tǒng)和服務(wù)是穩(wěn)定的,才能更好地完成業(yè)務(wù)指標(biāo)和整體的經(jīng)營目標(biāo)。

下面會講一下服務(wù)SLA保證的內(nèi)容。

首先SLA體現(xiàn)在對容量、性能、程度的約束,包括程度是多少的比例。那么要保證這個SLA約束和目標(biāo)達成,首先要把關(guān)鍵指標(biāo)監(jiān)控起來;第二是依賴治理、邏輯優(yōu)化;第三是負載均衡、服務(wù)分組和限流;第四是降級預(yù)案、容災(zāi)、壓測、在線演練等。

這是我們服務(wù)的關(guān)鍵指標(biāo)的監(jiān)控圖(見上圖)。支付回調(diào)服務(wù)要滿足8K QPS,99%的RT在30ms內(nèi),但是圖中監(jiān)控說明SLA未達到,RT程度指標(biāo)方面要優(yōu)化。

服務(wù)的SLA保證上,服務(wù)端超時和限流非常重要。如果沒有超時,很容易引起雪崩。

我們來講一個案例,有次商品服務(wù)響應(yīng)變慢,就導(dǎo)致上層的其他服務(wù)都慢,而且商品服務(wù)積壓了很多請求在線程池中,很多請求響應(yīng)過慢導(dǎo)致客戶端等待超時,客戶端早就放棄調(diào)用結(jié)果結(jié)束掉了,但是在商品服務(wù)線程池線程做處理時拿到這個請求還會處理,客戶都跑了,再去處理,客戶也拿不到這個結(jié)果,最后還會造成上層服務(wù)請求的堵塞,堵塞原因緩解時產(chǎn)生洪流。

限流是服務(wù)穩(wěn)定的最后一道保障。一個是HTTP服務(wù)的限流,一個是RPC服務(wù)的限流。我們服務(wù)的處理線程是Tesla框架分配的,所以服務(wù)限流可以做到非常精確,可以控制在服務(wù)級別和服務(wù)方法級別,也可以針對來源做限流。

我們做了這樣一系列改造之后,服務(wù)框架變成了有完善的監(jiān)控、有負載均衡、有服務(wù)分組和限流等完整管控能力的服務(wù)治理框架。服務(wù)分組之后,如果通用的服務(wù)崩潰了,購買鏈路的服務(wù)可以不受影響,這就做到了隔離。

這樣的一整套服務(wù)體系(如圖)就構(gòu)成了我們的服務(wù)架構(gòu)2.0,最終網(wǎng)站的可用性做到了99.979%,這是今年6月份的統(tǒng)計數(shù)據(jù)。我們還會逐步把服務(wù)的穩(wěn)定性和服務(wù)質(zhì)量做到更好。

5

總結(jié)及下一步展望

最后總結(jié)一下,服務(wù)框架的體系完善是一個漫長的發(fā)展過程,不需要一開始就很強、什么都有的服務(wù)框架,最早可能就是一個RPC框架。服務(wù)治理慢慢隨著業(yè)務(wù)量增長也會發(fā)展起來,服務(wù)治理是服務(wù)框架的重要組成部分。

另外,Tesla是為蘑菇街業(yè)務(wù)體系量身打造的服務(wù)框架??梢哉f服務(wù)框架是互聯(lián)網(wǎng)網(wǎng)站架構(gòu)的核心和持續(xù)發(fā)展的動力。選擇開源還是自建,要看團隊能力、看時機。我們要深度定制服務(wù)框架,所以選擇了自研,以后可能會開源出來。

服務(wù)框架是隨著業(yè)務(wù)發(fā)展不斷演變的,我們有1.0、1.5和2.0架構(gòu)的迭代。要前瞻性地謀劃和實施,要考慮未來三年、五年的容量。有一些系統(tǒng)瓶頸可能是要提前解決的,每一個場景不一樣,根據(jù)特定的場景選擇最合適的方案。

容量和性能關(guān)鍵字是一切可擴展、Cache、IO、異步化。目前我們正在做的是服務(wù)治理和SLA保障系統(tǒng)化,未來會做同城異地的雙活。

謝謝大家!

今日薦號:聊聊架構(gòu)

聊聊架構(gòu)是InfoQ旗下的垂直社區(qū),主要關(guān)注傳統(tǒng)企業(yè)以及互聯(lián)網(wǎng)企業(yè)的系統(tǒng)架構(gòu),研究并探討架構(gòu)實踐中的難點和痛點。定期組織線上群分享活動。

延展閱讀(點擊標(biāo)題):


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多