由12306.cn談?wù)劸W(wǎng)站性能技術(shù)

2012-01-17 09:31:57來源:愛范兒作者:

12306.cn網(wǎng)站掛了,被全國人民罵了。我這兩天也在思考這個事,我想以這個事來粗略地和大家討論一下網(wǎng)站性能的問題。因?yàn)閭}促,而且完全基于 本人有限的經(jīng)驗(yàn)和了解,所以,如果有什么問題還請大家一起討論和指正。(

12306.cn網(wǎng)站掛了,被全國人民罵了。我這兩天也在思考這個事,我想以這個事來粗略地和大家討論一下網(wǎng)站性能的問題。因?yàn)閭}促,而且完全基于 本人有限的經(jīng)驗(yàn)和了解,所以,如果有什么問題還請大家一起討論和指正。(這又是一篇長文,只討論性能問題,不討論那些UI,用戶體驗(yàn),或是是否把支付和購 票下單環(huán)節(jié)分開的功能性的東西)

業(yè)務(wù)

任何技術(shù)都離不開業(yè)務(wù)需求,所以,要說明性能問題,首先還是想先說說業(yè)務(wù)問題。

  • 其一,有人可能把這個東西和QQ或是網(wǎng)游相比。但我覺得這兩者是不一樣的,網(wǎng)游和QQ在線或是登錄時訪問的更多的是用戶自己的數(shù)據(jù),而訂票系統(tǒng)訪問的是中心的票量數(shù)據(jù),這是不一樣的。不要覺得網(wǎng)游或是QQ能行你就以為這是一樣的。網(wǎng)游和QQ 的后端負(fù)載相對于電子商務(wù)的系統(tǒng)還是簡單。
  • 其二,有人說春節(jié)期間訂火車的這個事好像網(wǎng)站的秒殺活動。的確很相似,但 是如果你的思考不在表面的話,你會發(fā)現(xiàn)這也有些不一樣;疖嚻边@個事,還有很多查詢操作,查時間,查座位,查鋪位,一個車次不 行,又查另一個車次,其伴隨著大量的查詢操作,下單的時候需要對數(shù)據(jù)庫操作。而秒殺,直接殺就好了。另外,關(guān)于秒殺,完全可以做成只接受前N個用戶的請求 (完全不操作后端的任何數(shù)據(jù), 僅僅只是對用戶的下單操作log),這種業(yè)務(wù),只要把各個服務(wù)器的時間精確同步了就可以了,無需在當(dāng)時操作任何數(shù)據(jù)庫。可以訂單數(shù)夠后,停止秒殺,然后批 量寫數(shù)據(jù)庫;疖嚻边@個豈止是秒殺那么簡單。能不能買到票得當(dāng)時告訴用戶啊。
  • 其三,有人拿這個系統(tǒng)和奧運(yùn)會的票務(wù)系統(tǒng)比較。我覺得還是不一樣。雖然奧運(yùn)會的票務(wù)系統(tǒng)當(dāng)年也一上線就廢了。但是奧運(yùn)會用的是抽獎的方式,也就是說不存在先來先得的搶的方式,而且,是事后抽獎,事前只需要收信息,事前不需要保證數(shù)據(jù)一致性,沒有鎖,很容易水平擴(kuò)展。
  • 其四訂票系統(tǒng)應(yīng)該和電子商務(wù)的訂單系統(tǒng)很相似,都是需要對庫存進(jìn) 行:1)占住庫存,2)支付(可選),3)扣除庫存的操作。這個是需要有一致性的檢查的,也就是在并發(fā)時需要對數(shù)據(jù)加鎖的。B2C的電商基本上都會把這個 事干成異步的,也就是說,你下的訂單并不是馬上處理的,而是延時處理的,只有成功處理了,系統(tǒng)才會給你一封確認(rèn)郵件說是訂單成功。我相信有很多朋友都收到 認(rèn)單不成功的郵件。這就是說,數(shù)據(jù)一致性在并發(fā)下是一個瓶頸。
  • 其五鐵路的票務(wù)業(yè)務(wù)很變態(tài),其采用的是突然放票,而有的票又遠(yuǎn)遠(yuǎn)不夠大家分,所以,大家才會有搶票這種有中國特色的業(yè)務(wù)的做法。于是當(dāng)票放出來的時候,就會有幾百萬人甚至上千萬人殺上去,查詢,下單。幾十分鐘內(nèi),一個網(wǎng)站能接受幾千萬的訪問量,這個是很恐怖的事情。據(jù)說12306的高峰訪問是10億PV,集中在早8點(diǎn)到10點(diǎn),每秒PV在高峰時上千萬。

多說幾句:

  • 庫存是B2C的惡夢,庫存管理相當(dāng)?shù)膹?fù)雜。不信,你可以問問所有傳統(tǒng)和電務(wù)零售業(yè)的企業(yè),看看他們管理庫存是多么難的一件事。不然,就不會有那么多人在問凡客的庫存問題了。(你還可以看看《喬布斯傳》,你就知道為什么Tim會接任Apple的CEO了,因?yàn)樗愣颂O果的庫存問題)
  • 對于一個網(wǎng)站來說,瀏覽網(wǎng)頁的高負(fù)載很容易搞定,查詢的負(fù)載有一定的難度去處理,不過還是可以通過緩存查詢結(jié)果來搞定,最難的就是下單的負(fù)載。因?yàn)橐L問庫存啊,對于下單,基本上是用異步來搞定的。去年雙11節(jié),淘寶的每小時的訂單數(shù)大約在60萬左右,京東一天也才能支持40萬(居然比12306還差),亞馬遜5年前一小時可支持70萬訂單量?梢,下訂單的操作并沒有我們相像的那么性能高。
  • 淘寶要比B2C的網(wǎng)站要簡單得多,因?yàn)闆]有倉庫,所以,不存在像B2C這樣有N個倉庫對同一商品庫存更新和查 詢的操作。下單的時候,B2C的 網(wǎng)站要去找一個倉庫,又要離用戶近,又要有庫存,這需要很多計(jì)算。試想,你在北京買了一本書,北京的倉庫沒貨了,就要從周邊的倉庫調(diào),那就要去看看沈陽或 是西安的倉庫有沒有貨,如果沒有,又得看看江蘇的倉庫,等等。淘寶的就沒有那么多事了,每個商戶有自己的庫存,庫存分到商戶頭上了,反而有利于性能。
  • 數(shù)據(jù)一致性才是真正的性能瓶頸。有 人說nginx可以搞定每秒10萬的靜態(tài)請求,我不懷疑。但這只是靜態(tài)請求,理論值,只要帶寬、I/O夠強(qiáng),服務(wù)器計(jì)算能力夠,并支持的并發(fā)連接數(shù)頂?shù)米?10萬TCP鏈接的建立 的話,那沒有問題。但在數(shù)據(jù)一致性面前,這10萬就完完全全成了一個可望不可及的理論值了。

我說那么多,我只是想從業(yè)務(wù)上告訴大家,我們需要從業(yè)務(wù)上真正了解春運(yùn)鐵路訂票這樣業(yè)務(wù)的變態(tài)之處。

前端性能優(yōu)化技術(shù)

要解決性能的問題,有很多種常用的方法,我在下面列舉一下,我相信12306這個網(wǎng)站使用下面的這些技術(shù)會讓其性能有質(zhì)的飛躍。

一、前端負(fù)載均衡

通過DNS的負(fù)載均衡器(一般在路由器上根據(jù)路由的負(fù)載重定向)可以把用戶的訪問均勻地分散在多個Web服務(wù)器上。這樣可以減少Web服務(wù)器的請求 負(fù)載。因?yàn)閔ttp的請求都是短作業(yè),所以,可以通過很簡單的負(fù)載均衡器來完成這一功能。最好是有CDN網(wǎng)絡(luò)讓用戶連接與其最近的服務(wù)器(CDN通常伴隨 著分布式存儲)。(關(guān)于負(fù)載均衡更為詳細(xì)的說明見“后端的負(fù)載均衡”)

二、減少前端鏈接數(shù)

我看了一下12306.cn,打開主頁需要建60多個HTTP連接,車票預(yù)訂頁面則有70多個HTTP請求,現(xiàn)在的瀏覽器都是并發(fā)請求的。所以,只 要有100萬個用戶,就會有6000萬個鏈接,太多了。一個登錄查詢頁面就好了。把js打成一個文件,把css也打成一個文件,把圖標(biāo)也打成一個文件,用 css分塊展示。把鏈接數(shù)減到最低。

三、減少網(wǎng)頁大小增加帶寬

這個世界不是哪個公司都敢做圖片服務(wù)的,因?yàn)閳D片太耗帶寬了。現(xiàn)在寬帶時代很難有人能體會到當(dāng)撥號時代做個圖頁都不敢用圖片的情形(現(xiàn)在在手機(jī)端瀏 覽也是這個情形)。我查看了一下12306首頁的需要下載的總文件大小大約在900KB左右,如果你訪問過了,瀏覽器會幫你緩存很多,只需下載10K左右 的文件。但是我們可以想像一個極端一點(diǎn)的案例,1百萬用戶同時訪問,且都是第一次訪問,每人下載量需要1M,如果需要在120秒內(nèi)返回,那么就需要,1M * 1M /120 * 8 = 66Gbps的帶寬。很驚人吧。所以,我估計(jì)在當(dāng)天,12306的阻塞基本上應(yīng)該是網(wǎng)絡(luò)帶寬,所以,你可能看到的是沒有響應(yīng)。后面隨著瀏覽器的緩存幫助 12306減少很多帶寬占用,于是負(fù)載一下就到了后端,后端的數(shù)據(jù)處理瓶頸一下就出來。于是你會看到很多http 500之類的錯誤。這說明服務(wù)器垮了。

四、前端頁面靜態(tài)化

靜態(tài)化一些不覺變的頁面和數(shù)據(jù),并gzip一下。還有一個并態(tài)的方法是把這些靜態(tài)頁面放在/dev/shm下,這個目錄就是內(nèi)存,直接從內(nèi)存中把文件讀出來返回,這樣可以減少昂貴的磁盤I/O。

五、優(yōu)化查詢

很多人查詢都是在查一樣的,完全可以用反向代理合并這些并發(fā)的相同的查詢。這樣的技術(shù)主要用查詢結(jié)果緩存來實(shí)現(xiàn),第一次查詢走數(shù)據(jù)庫獲得數(shù)據(jù),并把 數(shù)據(jù)放到緩存,后面的查詢統(tǒng)統(tǒng)直接訪問高速緩存。為每個查詢做Hash,使用NoSQL的技術(shù)可以完成這個優(yōu)化。(這個技術(shù)也可以用做靜態(tài)頁面)

對于火車票量的查詢,個人覺得不要顯示數(shù)字,就顯示一個“有”或“無”就好了,這樣可以大大簡化系統(tǒng)復(fù)雜度,并提升性能。

六、緩存的問題

緩存可以用來緩存動態(tài)頁面,也可以用來緩存查詢的數(shù)據(jù)。緩存通常有那么幾個問題:

1)緩存的更新。也叫緩存和數(shù)據(jù)庫的同步。有這么幾種方法,一是緩存time out,讓緩存失效,重查,二是,由后端通知更新,一量后端發(fā)生變化,通知前端更新。前者實(shí)現(xiàn)起來比較簡單,但實(shí)時性不高,后者實(shí)現(xiàn)起來比較復(fù)雜 ,但實(shí)時性高。

2)緩存的換頁。內(nèi)存可能不夠,所以,需要把一些不活躍的數(shù)據(jù)換出內(nèi)存,這個和操作系統(tǒng)的內(nèi)存換頁和交換內(nèi)存很相似。FIFO、LRU、LFU都是比較經(jīng)典的換頁算法。相關(guān)內(nèi)容參看Wikipeida的緩存算法。

3)緩存的重建和持久化。緩存在內(nèi)存,系統(tǒng)總要維護(hù),所以,緩存就會丟失,如果緩存沒了,就需要重建,如果數(shù)據(jù)量很大,緩存重建的過程會很慢,這會影響生產(chǎn)環(huán)境,所以,緩存的持久化也是需要考慮的。

諸多強(qiáng)大的NoSQL都很好支持了上述三大緩存的問題。

后端性能優(yōu)化技術(shù)

前面討論了前端性能的優(yōu)化技術(shù),于是前端可能就不是瓶頸問題了。那么性能問題就會到后端數(shù)據(jù)上來了。下面說幾個后端常見的性能優(yōu)化技術(shù)。

一、數(shù)據(jù)冗余

關(guān)于數(shù)據(jù)冗余,也就是說,把我們的數(shù)據(jù)庫的數(shù)據(jù)冗余處理,也就是減少表連接這樣的開銷比較大的操作,但這樣會犧牲數(shù)據(jù)的一致性。風(fēng)險(xiǎn)比較大。很多人 把NoSQL用做數(shù)據(jù),快是快了,因?yàn)閿?shù)據(jù)冗余了,但這對數(shù)據(jù)一致性有大的風(fēng)險(xiǎn)。這需要根據(jù)不同的業(yè)務(wù)進(jìn)行分析和處理。(注意:用關(guān)系型數(shù)據(jù)庫很容易移植 到NoSQL上,但是反過來從NoSQL到關(guān)系型就難了)

二、數(shù)據(jù)鏡像

幾乎所有主流的數(shù)據(jù)庫都支持鏡像,也就是replication。數(shù)據(jù)庫的鏡像帶來的好處就是可以做負(fù)載均衡。把一臺數(shù)據(jù)庫的負(fù)載均分到多臺上,同時又保證了數(shù)據(jù)一致性(Oracle的SCN)。最重要的是,這樣還可以有高可用性,一臺廢了,還有另一臺在服務(wù)。

數(shù)據(jù)鏡像的數(shù)據(jù)一致性可能是個問題,所以我們要吧在單條數(shù)據(jù)上進(jìn)行數(shù)據(jù)分區(qū),也就是說,把一個暢銷商品的庫存均分到不同的服務(wù)器上,如,一個暢銷商品有1萬的庫存,我們可以設(shè)置10臺服務(wù)器,每臺服務(wù)器上有100個庫存,這就好像B2C的倉庫一樣。

三、數(shù)據(jù)分區(qū)

數(shù)據(jù)鏡像不能解決的一個問題就是數(shù)據(jù)表里的記錄太多,導(dǎo)致數(shù)據(jù)庫操作太慢。所以,把數(shù)據(jù)分區(qū)。數(shù)據(jù)分區(qū)有很多種做法,一般來說有下面這幾種:

1)把數(shù)據(jù)把某種邏輯來分類。比如火車票的訂票系統(tǒng)可以按各鐵路局來分,可按各種車型分,可以按始發(fā)站分,可以按目的地分……,反正就是把一張表拆成多張有一樣的字段但是不同種類的表,這樣,這些表就可以存在不同的機(jī)器上以達(dá)到分擔(dān)負(fù)載的目的。

2)把數(shù)據(jù)按字段分,也就是堅(jiān)著分表。比如把一些不經(jīng)常改的數(shù)據(jù)放在一個表里,經(jīng)常改的數(shù)據(jù)放在另一個表里。把一張表變成1對1的關(guān)系,這樣,你可 以減少表的字段個數(shù),同樣可以提升一定的性能。另外,字段多會造成一條記錄的存儲會被放到不同的頁表里,這對于讀寫性能都有問題。

3)平均分表。因?yàn)榈谝环N方法是并不一定平均分均,可能某個種類的數(shù)據(jù)還是很多。所以,也有采用平均分配的方式,通過主鍵ID的范圍來分表。

4)同一數(shù)據(jù)分區(qū)。這個在上面數(shù)據(jù)鏡像提過。也就是把同一商品的庫存值分到不同的服務(wù)器上,比如有10000個庫存,可以分到10臺服務(wù)器上,一臺上有1000個庫存。然后負(fù)載均衡。

這三種分區(qū)都有好有壞。最常用的還是第一種。數(shù)據(jù)一量分區(qū),你就需要有一個或是多個調(diào)度來讓你的前端程序知道去哪里找數(shù)據(jù)。把火車票的數(shù)據(jù)分區(qū),并放在各個省市,會對12306這個系統(tǒng)有非常有意義的質(zhì)的性能的提高。

四、后端系統(tǒng)負(fù)載均衡

前面說了數(shù)據(jù)分區(qū),數(shù)據(jù)分區(qū)可以在一定程度上減輕負(fù)載,但是無法減輕熱銷商品的負(fù)載,對于火車票來說,可以認(rèn)為是大城市的某些主干線上的車票。這就 需要使用數(shù)據(jù)鏡像來減輕負(fù)載。使用數(shù)據(jù)鏡像,你必然要使用負(fù)載均衡,在后端,我們可能很難使用像路由器上的負(fù)載均衡器,因?yàn)槟鞘蔷饬髁康,因(yàn)榱髁坎⒉?代表服務(wù)器的繁忙程序。因此,我們需要一個任務(wù)分配系統(tǒng),其還能監(jiān)控各個服務(wù)器的負(fù)載情況。

任務(wù)分配服務(wù)器有一些難點(diǎn):

  • 負(fù)載情況比較復(fù)雜。什么叫忙?是CPU高?還是磁盤I/O高?還是內(nèi)存使用高?還是并發(fā)高?你可能需要全部都要考慮。這些信息要發(fā)送給那個任務(wù)分配器上,由任務(wù)分配器挑選一臺負(fù)載最輕的服務(wù)器來處理。
  • 任務(wù)分配服務(wù)器上需要對任務(wù)隊(duì)列,不能丟任務(wù)啊,所以還需要持久化。并且可以以批量的方式把任務(wù)分配給計(jì)算服務(wù)器。
  • 任務(wù)分配服務(wù)器死了怎么辦?這里需要一些如Live-Standby或是failover等高可用性的技術(shù)。我們還需要注意那些持久化了的任務(wù)的隊(duì)列如果轉(zhuǎn)移到別的服務(wù)器上的問題。

我看到有很多系統(tǒng)都用靜態(tài)的方式來分配,有的用hash,有的就簡單地輪流分析。這些都不夠好,一個是不能完美地負(fù)載均衡,另一個靜態(tài)的方法的致命缺陷是,如果有一臺計(jì)算服務(wù)器死機(jī)了,或是我們需要加入新的服務(wù)器,對于我們的分配器來說,都需要知道。

還有一種方法是使用搶占式的方式進(jìn)行負(fù)載均衡,由下游的計(jì)算服務(wù)器去任務(wù)服務(wù)器上拿任務(wù)。讓這些計(jì)算服務(wù)器自己決定自己是否要任務(wù)。這樣的好處是可 以簡化系統(tǒng)的復(fù)雜度,而且還可以任意實(shí)時地減少或增加計(jì)算服務(wù)器。但是唯一不好的就是,如果有一些任務(wù)只能在某種服務(wù)器上處理,這可能會引入一些復(fù)雜度。 不過總體來說,這種方法可能是比較好的負(fù)載均衡。

五、異步、 throttle 和 批量處理

異步、throttle(節(jié)流閥) 和批量處理都需要對并發(fā)請求數(shù)做隊(duì)列處理的。

  • 異步在業(yè)務(wù)上一般來說就是收集請求,然后延時處理。在技術(shù)上就是可以把各個處理程序做成并行的,也就可以水平擴(kuò)展了。但是異步的技術(shù)問題大概有這 些,a)被調(diào)用方的結(jié)果返回,會涉及進(jìn)程線程間通信的問題。b)如果程序需要回滾,回滾會有點(diǎn)復(fù)雜。c)異步通常都會伴隨多線程多進(jìn)程,并發(fā)的控制也相對 麻煩一些。d)很多異步系統(tǒng)都用消息機(jī)制,消息的丟失和亂序也會是比較復(fù)雜的問題。
  • throttle 技術(shù)其實(shí)并不提升性能,這個技術(shù)主要是防止系統(tǒng)被超過自己不能處理的流量給搞垮了,這其實(shí)是個保護(hù)機(jī)制。使用throttle技術(shù)一般來說是對于一些自己無法控制的系統(tǒng),比如,和你網(wǎng)站對接的銀行系統(tǒng)。
  • 批量處理的技術(shù),是把一堆基本相同的請求批量處理。比如,大家同時購買同一個商品,沒有必要你買一個我就寫一次數(shù)據(jù)庫,完全可以收集到一定數(shù)量的 請求,一次操作。這個技術(shù)可以用作很多方面。比如節(jié)省網(wǎng)絡(luò)帶寬,我們都知道網(wǎng)絡(luò)上的MTU(最大傳輸單元),以態(tài)網(wǎng)是1500字節(jié),光纖可以達(dá)到4000 多個字節(jié),如果你的一個網(wǎng)絡(luò)包沒有放滿這個MTU,那就是在浪費(fèi)網(wǎng)絡(luò)帶寬,因?yàn)榫W(wǎng)卡的驅(qū)動程序只有一塊一塊地讀效率才會高。因此,網(wǎng)絡(luò)發(fā)包時,我們需要收 集到足夠多的信息后再做網(wǎng)絡(luò)I/O,這也是一種批量處理的方式。批量處理的敵人是流量低,所以,批量處理的系統(tǒng)一般都會設(shè)置上兩個閥值,一個是作業(yè)量,另 一個是timeout,只要有一個條件滿足,就會開始提交處理。

所以,只要是異步,一般都會有throttle機(jī)制,一般都會有隊(duì)列來排隊(duì),有隊(duì)列,就會有持久化,而系統(tǒng)一般都會使用批量的方式來處理。

云風(fēng)同學(xué)設(shè)計(jì)的“排隊(duì)系統(tǒng)” 就是這個技術(shù)。這和電子商務(wù)的訂單系統(tǒng)很相似,就是說,我的系統(tǒng)收到了你的購票下單請求,但是我還沒有真正處理,我的系統(tǒng)會跟據(jù)我自己的處理能力來throttle住這些大量的請求,并一點(diǎn)一點(diǎn)地處理。一旦處理完成,我就可以發(fā)郵件或短信告訴用戶你來可以真正購票了。

在這里,我想通過業(yè)務(wù)和用戶需求方面討論一下云風(fēng)同學(xué)的這個排隊(duì)系統(tǒng),因?yàn)槠鋸募夹g(shù)上看似解決了這個問題,但是從業(yè)務(wù)和用戶需求上來說可能還是有一些值得我們?nèi)ド钊胨伎嫉牡胤剑?/p>

1)隊(duì)列的DoS攻擊。首先,我們思考一下,這個隊(duì) 是個單純地排隊(duì)的嗎?這樣做還不夠好,因?yàn)檫@樣我們不能杜絕黃牛,而且單純的ticket_id很容易發(fā)生DoS攻擊,比如,我發(fā)起N個 ticket_id,進(jìn)入購票流程后,我不買,我就耗你半個小時,很容易我就可以讓想買票的人幾天都買不到票。有人說,用戶應(yīng)該要用身份證來排隊(duì), 這樣在購買里就必需要用這個身份證來買,但這也還不能杜絕黃牛排隊(duì)或是號販子。因?yàn)樗麄兛梢宰訬個帳號來排隊(duì),但就是不買。黃牛這些人這個時候只需要干 一個事,把網(wǎng)站搞得正常不能訪問,讓用戶只能通過他們來買。

2)對列的一致性?對這個隊(duì)列的操作是不是需要鎖?只要有鎖,性能一定上不去。試想,100萬個人同時要求你來分配位置號,這個隊(duì)列將會成為性能瓶頸。你一定沒有數(shù)據(jù)庫實(shí)現(xiàn)得性能好,所以,可能比現(xiàn)在還差

3)隊(duì)列的等待時間。購票時間半小時夠不夠?多不 多?要是那時用戶正好不能上網(wǎng)呢?如果時間短了,用戶也會抱怨,如果時間長了,后面在排隊(duì)的那些人也會抱怨。這個方法可能在實(shí)際操作上會有很多問題。另 外,半個小時太長了,這完全不現(xiàn)實(shí),我們用15分鐘來舉例:有1千萬用戶,每一個時刻只能放進(jìn)去1萬個,這1萬個用戶需要15分鐘完成所有操作,那么,這 1千萬用戶全部處理完,需要1000*15m = 250小時,10天半,火車早開了。(我并亂說,根據(jù)鐵道部專家的說明:這幾天,平均一天下單100萬,所以,處理1000萬的用戶需要十天。這個計(jì)算可能有點(diǎn)簡單了,我只是想說,在這樣低負(fù)載的系統(tǒng)下用排隊(duì)可能都不能解決問題

4)隊(duì)列的分分式。這個排隊(duì)系統(tǒng)只有一個隊(duì)列好嗎? 還不足夠好。因?yàn),如果你放進(jìn)去的可以購票的人如果在買同一個車次的同樣的類型的票(比如某動車臥鋪),還是等于在搶票,也就是說系統(tǒng)的負(fù)載還是會有可能 集中到其中某臺服務(wù)器上。因此,最好的方法是根據(jù)用戶的需求——提供出發(fā)地和目的地,來對用戶進(jìn)行排隊(duì)。而這樣一來,隊(duì)列也就可以是多個,只要是多個隊(duì) 列,就可以水平擴(kuò)展了。

我覺得完全可以向網(wǎng)上購物學(xué)習(xí)。在排隊(duì)(下單)的時候,收集好用戶的信息和想要買的票,并允許用戶設(shè)置購票的優(yōu)先級,比如,A車次臥鋪買 不到就買 B車次的臥鋪,如果還買不到就買硬座等等,然后用戶把所需的錢先充值好,接下來就是系統(tǒng)完全自動地異步處理訂單。成功不成功都發(fā)短信或郵件通知用戶。這 樣,系統(tǒng)不僅可以省去那半個小時的用戶交互時間,自動化加快處理,還可以合并相同購票請求的人,進(jìn)行批處理(減少數(shù)據(jù)庫的操作次數(shù))。這種方法最妙的事是 可以知道這些排隊(duì)用戶的需求,不但可以優(yōu)化用戶的隊(duì)列,把用戶分布到不同的隊(duì)列,還可以像亞馬遜的心愿單一樣,讓鐵道部做車次統(tǒng)籌安排和調(diào)整(最后,排隊(duì) 系統(tǒng)(下單系統(tǒng))還是要保存在數(shù)據(jù)庫里的或做持久化,不能只放在內(nèi)存中,不然機(jī)器一down,就等著被罵吧)。

小結(jié)

寫了那么多,我小結(jié)一下:

0)無論你怎么設(shè)計(jì),你的系統(tǒng)一定要能容易地水平擴(kuò)展。也就是說,你的整個數(shù)據(jù)流中,所有的環(huán)節(jié)都要能夠水平擴(kuò)展。這樣,當(dāng)你的系統(tǒng)有性能問題時,“加3倍的服務(wù)器”才不會被人譏笑。

1)上述的技術(shù)不是一朝一夕能搞定的,沒有長期的積累,基本無望。

2)集中式的賣票很難搞定,使用上述的技術(shù)可以讓訂票系統(tǒng)能有幾佰倍的性能提升。而在各個省市建分站,分開賣票,是能讓現(xiàn)有系統(tǒng)性能有質(zhì)的提升的最好方法。

3)春運(yùn)前夕搶票且票量供遠(yuǎn)小于求這種業(yè)務(wù)模式是相當(dāng)變態(tài)的,讓幾千萬甚至上億的人在某個早晨的8點(diǎn)鐘同時登錄同時搶票的這種業(yè)務(wù)模式是變態(tài)中的變態(tài)。業(yè)務(wù)形態(tài)的變態(tài)決定了無論他們怎么辦干一定會被罵。

4)為了那么一兩個星期而搞那么大的系統(tǒng),而其它時間都在閑著,也就是鐵路才干得出來這樣的事了。

關(guān)鍵詞:12306火車票

贊助商鏈接: