建設一個靠譜的火車票網(wǎng)上訂購系統(tǒng)

愛范兒
0 評論 3662 瀏覽 12 收藏 13 分鐘
🔗 产品经理的不可取代的价值是能够准确发现和满足用户需求,把需求转化为产品,并协调资源推动产品落地,创造商业价值。

昨天,2012年1月11日,網(wǎng)友 @fenng 寫了一篇文章,批評鐵道部火車票網(wǎng)上訂購系統(tǒng),http://www.12306.cn?[1]。同時在新浪發(fā)了一條言辭激烈的微博,引起熱議 [2]。

春節(jié)將到,大家買不著車票,趕不上大年三十與家人團聚,急切心情可以理解。但是拍桌子開罵,只能宣泄情緒,解決不了實際問題。

開發(fā)一套訂票系統(tǒng)并不難,難在應對春運期間,日均 10 億級別的洪峰流量。日均 10 億級別的洪峰請求,在中國這個人口全球第一大國,不算稀罕,不僅火車票訂票系統(tǒng)會遇到,而且電子商務在促銷時,也會遇到,社交網(wǎng)站遇到新聞熱點時,也會遇到。

所以,能夠在中國成功運行的云計算系統(tǒng),推廣到全球,一定也能成功。但是在美國成功運行的云計算系統(tǒng),移植到中國,卻不一定成功。

如果我們能夠設計建造一套,穩(wěn)定而高效的鐵路訂票系統(tǒng),不僅解決了中國老百姓的實際問題,而且在全球高科技業(yè)界,也是一大亮點,而且是貼著中國標簽的前沿科技的亮點。

于是軟件工程師們獻計獻策,討論如何改進 12306 網(wǎng)上購票系統(tǒng) [3]。其中比較有代表性的,有兩篇 [4,5]。

網(wǎng)友的評論中,有觀點認為,[4] 利用“虛擬排隊”的手段,將過程拉長負載降低,是網(wǎng)游的設計思路。而 [5] 利用緩存技術(shù),一層層地降低系統(tǒng)負荷, 是互聯(lián)網(wǎng)的設計思路。

個人認為,[4] 和 [5] 并不是相互排斥的兩種路線,兩者著重解決的問題不同,不妨結(jié)合起來使用,取長補短。下面介紹一下我們的設計草案,追求實用,擯棄花哨。拋磚引玉,歡迎拍磚。

圖一。12306.cn 網(wǎng)站系統(tǒng)架構(gòu)設想圖。

Courtesy?http://alibuybuy-img11.stor.sinaapp.com/2012/01/e990_12306.png

圖一是系統(tǒng)架構(gòu)圖,典型的“展現(xiàn)層”/ “業(yè)務層”/ “數(shù)據(jù)層”的三段論。

用戶接入有兩類,一個是運行在電腦里的瀏覽器,例如 IE,另一個是手機。

無論用戶用電腦瀏覽器,還是手機訪問 http://www.12306.cn 網(wǎng)站,用戶請求首先被網(wǎng)站的負載均衡器接收。負載均衡器連接著一群門戶服務器,根據(jù)各個門戶服務器的負載輕重,負載均衡器把用戶請求,轉(zhuǎn)發(fā)到某一相對清閑的門戶服務器。

門戶服務器的任務類似于收發(fā)室老頭兒,它只讀每個用戶請求的前幾個 bytes,目的是確定用戶請求的類型,然后把請求投放到相應類型的隊列中去。門戶服務器的處理邏輯非常簡單,這樣做的好處,是讓它能夠快速處理大批量用戶請求。

根據(jù) [5] 的分析,12306 處理的用戶請求,大致分為三類,

1. 查詢。用戶訂票前,查詢車次以及余票。用戶下訂單后,查詢是否已經(jīng)訂上票。
2. 訂票,包括確定車次和票數(shù),然后付款。用戶付款時,需要在網(wǎng)銀等網(wǎng)站上操作。
3. 第一次訪問的用戶,需要登記,包括姓名和信用卡等信息。

三類請求的業(yè)務處理過程,被分為兩個階段,

1. 運行于緩存中的任務隊列。設置隊列的目的,是防止處理過程耗時太長,導致大量用戶請求擁塞于門戶服務器,導致系統(tǒng)癱瘓。

2. 業(yè)務處理處理器,對于每一類業(yè)務,分別有一群業(yè)務服務器。不同業(yè)務的處理流程,各不相同。

 

圖二。12306.cn 網(wǎng)站查詢和訂票業(yè)務流程設想圖。

Courtesy?http://alibuybuy-img11.stor.sinaapp.com/2012/01/1e0d_12306-1.png

圖二描述了查詢和訂票,兩個業(yè)務的處理流程。登記業(yè)務流程從略。

查詢的業(yè)務流程,參見圖二上半部,分五步。這里有兩個問題需要注意,

1. 用戶發(fā)出請求后,經(jīng)過短暫的等待時間,能夠迅速看到結(jié)果。平均等待時間不能超過 1 秒。

2. 影響整個查詢速度的關(guān)鍵,是“查詢服務器”的設計。

查詢?nèi)蝿湛梢赃M一步細化,大致分成三種。

1. 查詢車次和時間表,這是靜態(tài)內(nèi)容,很少與數(shù)據(jù)庫交互,數(shù)據(jù)量也不大,可以緩存在內(nèi)存中。

車次和時間表的數(shù)據(jù)結(jié)構(gòu),不妨采用 Key-Value 的方式,開發(fā)簡單,使用效率高。Key-Value 的具體實現(xiàn)有很多產(chǎn)品,[5] 建議使用 Redis。

這些是技術(shù)細節(jié),不妨通過對比實驗,針對火車票訂票系統(tǒng)的實際流量,以及峰值波動,確定哪一個產(chǎn)品最合適。

2. 查詢某一班次的剩余車票,這需要調(diào)用數(shù)據(jù)庫中不斷更新的數(shù)據(jù)。

[5] 建議把剩余車票只分為兩種,“有”或“無”,這樣減少調(diào)用訪問數(shù)據(jù)庫的次數(shù),降低數(shù)據(jù)庫的壓力。但是這樣做,不一定能夠滿足用戶的需求,說不定會招致網(wǎng)友的批評譏諷。

[4] 建議在訂票隊列中,增加測算訂票隊列長度的功能,根據(jù)訂票隊列長度以及隊列中每個請求的購票數(shù)量,可以計算出每個車次的剩余座位。如果 12306.cn 網(wǎng)站只有一個后臺系統(tǒng),這個辦法行之有效。

但是假如 12306.cn 網(wǎng)站采用分布式結(jié)構(gòu),每個鐵路分局設有子系統(tǒng),分別管理各個鐵路分局轄區(qū)內(nèi)的各個車次。在分布式系統(tǒng)下,這個辦法面臨任務轉(zhuǎn)發(fā)的麻煩。不僅開發(fā)工作量大,而且會延長查詢流程處理時間,導致用戶長久等待。

3. 已經(jīng)下單的用戶,查詢是否已經(jīng)成功地訂上票。

每個用戶通常只關(guān)心自己訂的票。如果把每個用戶訂購的車票的所有內(nèi)容,都緩存在內(nèi)存里,不僅非常耗用內(nèi)存空間,內(nèi)存空間使用效率低下,更嚴重的問題是,訪問數(shù)據(jù)庫過于頻繁,數(shù)據(jù)量大,增大數(shù)據(jù)庫的壓力。

解決上述分布式同步,以及數(shù)據(jù)庫壓力的兩個問題,不妨從訂票的流程設計和數(shù)據(jù)結(jié)構(gòu)設計入手。

假如有個北京用戶在網(wǎng)上訂購了一套聯(lián)票,途經(jīng)北京鐵路局和鄭州鐵路局轄區(qū)的兩個車次。用戶從北京上網(wǎng),由北京鐵路局的子系統(tǒng),處理他的請求。北京鐵路局的訂票服務器把他的請求一分為二,北京鐵路局的車次的訂票,在北京子系統(tǒng)完成,鄭州鐵路局的車次在鄭州子系統(tǒng)完成。

每個子系統(tǒng)處理四種 Key-Value 數(shù)據(jù)組。

1. 用戶ID:多個 (訂單ID)s。
2. 訂單ID:多個 (訂票結(jié)果ID)s。
3. 訂票結(jié)果ID: ?一個 (用戶ID,車次ID)。
4. 車次ID:一個(日期),多個 (座位,用戶ID)。

北京訂票服務器完成訂票后,把上述四個數(shù)據(jù)組,寫入北京子系統(tǒng)的數(shù)據(jù)庫,同時緩存進北京的查詢服務器,參見圖二下半部第6步和第7步。

鄭州訂票服務器完成訂票后,把上述四個數(shù)據(jù)組,寫入鄭州子系統(tǒng)的數(shù)據(jù)庫,同時緩存進北京的查詢服務器,而不是鄭州的服務器。

讓訂票服務器把訂票數(shù)據(jù),同時寫入數(shù)據(jù)庫和查詢服務器的緩存,目的是讓數(shù)據(jù)庫永久保留訂票記錄,而讓大多數(shù)查詢,只訪問緩存,降低數(shù)據(jù)庫的壓力。

北京用戶的訂票數(shù)據(jù),只緩存在北京的查詢服務器,不跨域緩存,從而降低緩存空間的占用,和同步的麻煩。這樣做,有個前提假設,查詢用戶與訂票用戶,基本上是同一個人,而且從同一個城市上網(wǎng)。

但是這里有個缺陷,某用戶在北京上網(wǎng)訂了票。過了幾天,他在北京上網(wǎng),輸入用戶ID和密碼后,就會看到他訂購的所有車票。可是又過了幾天,他去了鄭州,從鄭州上網(wǎng),同樣輸入用戶ID和密碼,卻看不到他訂購的所有車票。

解決這個缺陷的辦法并不麻煩,在用戶查詢訂票信息時,需要注明訂票地點,系統(tǒng)根據(jù)訂票地點,把查詢請求轉(zhuǎn)發(fā)到相應區(qū)域的子系統(tǒng)。

另外,每次訂票的時候,網(wǎng)站會給他的手機發(fā)送短信,提供訂票信息,參見圖二下半部第8步和第9步。

以上是一個初步設計,還有不少細節(jié)需要完善,例如防火墻如何布置等等。這個設計不僅適用于單一的集中式部署,而且也適合分布式部署。

或許有讀者會問,為什么沒有用到云計算?其實上述架構(gòu)設計,為將來向云計算演變,留下了伏筆。

在上述架構(gòu)設計中,我們假定每個環(huán)節(jié)需要用多少服務器,需要多大容量的數(shù)據(jù)庫,預先都已經(jīng)規(guī)劃好。但是假如事先的規(guī)劃,低于實際承受的流量和數(shù)據(jù)量,那么系統(tǒng)就會崩潰。所以,事先的規(guī)劃,只能以峰值為基準設立。

但是峰值將會是多少?事先難以確定。即便能夠確定峰值,然后以峰值為基準,規(guī)劃系統(tǒng)的能力,那么春運過后,就會有大量資源冗余,造成資源浪費?

如何既能抗洪,又不造成資源浪費?解決方案是云計算,而且目前看來,除了云計算,沒有別的辦法。

Reference,

[1] 海量事務高速處理系統(tǒng)。

http://www.douban.com/note/195179318/

[2]?http://weibo.com/1577826897/y0jGYcZfW

[3] 火車訂票系統(tǒng)的設想。

http://weibo.com/1570303725/y0l9Y2mwE

[4] 鐵路訂票系統(tǒng)的簡單設計。

http://blog.codingnow.com/2012/01/ticket_queue.html

[5] 鐵路訂票網(wǎng)站個人的設計淺見。

http://hi.baidu.com/caoz/blog/item/f4f1d7caee09b558f21fe780.html

題圖來自?Designyoutrust

來源:http://www.ifanr.com/68019

作者:張成晨

來源公眾號:愛范兒(ID:ifanr);連接熱愛,創(chuàng)造不同。

本文由人人都是產(chǎn)品經(jīng)理合作媒體 @愛范兒 授權(quán)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,禁止轉(zhuǎn)載。

題圖來自Unsplash,基于CC0協(xié)議

該文觀點僅代表作者本人,人人都是產(chǎn)品經(jīng)理平臺僅提供信息存儲空間服務。

更多精彩內(nèi)容,請關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發(fā)揮!
专题
13875人已学习13篇文章
产品体验报告,是体验者在深入了解某个产品的商业模式、使用场景、产品功能等方面后,所作出的先有深度再到广度的图文分析报告。本专题的文章分享了不同产品的体验报告。
专题
12129人已学习15篇文章
本专题的文章分享了如何制定业务指标?
专题
14233人已学习13篇文章
数据仓库是所有产品的数据中心,公司体系下的所有产品产生的所有数据最终都流向数据仓库。本专题的文章分享了什么是数据仓库和如何搭建数据仓库。
专题
32104人已学习10篇文章
社交产品是大坑?没get到这些知识点,可能你才是个大坑。
专题
13260人已学习12篇文章
随着“新基建”的号角,新技术不断涌现,数字化转型成了成了大多数企业的迫切需求。本专题的文章分享了如何做服务数字化转型。
专题
13309人已学习12篇文章
需求管理,也是产品运营人工作中非常重要的一个任务。本专题的文章分享了如何做需求管理。