paulwong

          My Links

          Blog Stats

          常用鏈接

          留言簿(67)

          隨筆分類(1389)

          隨筆檔案(1147)

          文章分類(7)

          文章檔案(10)

          相冊(cè)

          收藏夾(2)

          AI

          Develop

          E-BOOK

          Other

          養(yǎng)生

          微服務(wù)

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          60天內(nèi)閱讀排行

          [轉(zhuǎn)帖]建設(shè)一個(gè)靠譜的火車票網(wǎng)上訂購(gòu)系統(tǒng)

          轉(zhuǎn)自【 http://www.ifanr.com/68019
          昨天,2012年1月11日,網(wǎng)友 @fenng 寫了一篇文章,批評(píng)鐵道部火車票網(wǎng)上訂購(gòu)系統(tǒng),http://www.12306.cn [1]。同時(shí)在新浪發(fā)了一條言辭激烈的微博,“去你的‘海量事務(wù)高速處理系統(tǒng)’”,引起熱議 [2]。

          春節(jié)將到,大家買不著車票,趕不上大年三十與家人團(tuán)聚,急切心情可以理解。但是拍桌子開(kāi)罵,只能宣泄情緒,解決不了實(shí)際問(wèn)題。 開(kāi)發(fā)一套訂票系統(tǒng)并不難,難在應(yīng)對(duì)春運(yùn)期間,日均 10 億級(jí)別的洪峰流量。日均 10 億級(jí)別的洪峰請(qǐng)求,在中國(guó)這個(gè)人口全球第一大國(guó),不算稀罕,不僅火車票訂票系統(tǒng)會(huì)遇到,而且電子商務(wù)在促銷時(shí),也會(huì)遇到,社交網(wǎng)站遇到新聞熱點(diǎn)時(shí),也會(huì)遇到。 所以,能夠在中國(guó)成功運(yùn)行的云計(jì)算系統(tǒng),推廣到全球,一定也能成功。

          但是在美國(guó)成功運(yùn)行的云計(jì)算系統(tǒng),移植到中國(guó),卻不一定成功。 如果我們能夠設(shè)計(jì)建造一套,穩(wěn)定而高效的鐵路訂票系統(tǒng),不僅解決了中國(guó)老百姓的實(shí)際問(wèn)題,而且在全球高科技業(yè)界,也是一大亮點(diǎn),而且是貼著中國(guó)標(biāo)簽的前沿科技的亮點(diǎn)。 于是軟件工程師們獻(xiàn)計(jì)獻(xiàn)策,討論如何改進(jìn) 12306 網(wǎng)上購(gòu)票系統(tǒng) [3]。其中比較有代表性的,有兩篇 [4,5]。 網(wǎng)友的評(píng)論中,有觀點(diǎn)認(rèn)為,[4] 利用“虛擬排隊(duì)”的手段,將過(guò)程拉長(zhǎng)負(fù)載降低,是網(wǎng)游的設(shè)計(jì)思路。而 [5] 利用緩存技術(shù),一層層地降低系統(tǒng)負(fù)荷, 是互聯(lián)網(wǎng)的設(shè)計(jì)思路。 個(gè)人認(rèn)為,[4] 和 [5] 并不是相互排斥的兩種路線,兩者著重解決的問(wèn)題不同,不妨結(jié)合起來(lái)使用,取長(zhǎng)補(bǔ)短。

          下面介紹一下我們的設(shè)計(jì)草案,追求實(shí)用,擯棄花哨。拋磚引玉,歡迎拍磚。
          圖一。12306.cn 網(wǎng)站系統(tǒng)架構(gòu)設(shè)想圖。
          Courtesy http://i879.photobucket.com/albums/ab351/kan_deng/12306.png

          圖一是系統(tǒng)架構(gòu)圖,典型的“展現(xiàn)層”/ “業(yè)務(wù)層”/ “數(shù)據(jù)層”的三段論。 用戶接入有兩類,一個(gè)是運(yùn)行在電腦里的瀏覽器,例如 IE,另一個(gè)是手機(jī)。 無(wú)論用戶用電腦瀏覽器,還是手機(jī)訪問(wèn) http://www.12306.cn 網(wǎng)站,用戶請(qǐng)求首先被網(wǎng)站的負(fù)載均衡器接收。負(fù)載均衡器連接著一群門戶服務(wù)器,根據(jù)各個(gè)門戶服務(wù)器的負(fù)載輕重,負(fù)載均衡器把用戶請(qǐng)求,轉(zhuǎn)發(fā)到某一相對(duì)清閑的門戶服務(wù)器。 門戶服務(wù)器的任務(wù)類似于收發(fā)室老頭兒,它只讀每個(gè)用戶請(qǐng)求的前幾個(gè) bytes,目的是確定用戶請(qǐng)求的類型,然后把請(qǐng)求投放到相應(yīng)類型的隊(duì)列中去。門戶服務(wù)器的處理邏輯非常簡(jiǎn)單,這樣做的好處,是讓它能夠快速處理大批量用戶請(qǐng)求。

          根據(jù) [5] 的分析,12306 處理的用戶請(qǐng)求,大致分為三類,
          1. 查詢。用戶訂票前,查詢車次以及余票。用戶下訂單后,查詢是否已經(jīng)訂上票。
          2. 訂票,包括確定車次和票數(shù),然后付款。用戶付款時(shí),需要在網(wǎng)銀等網(wǎng)站上操作。
          3. 第一次訪問(wèn)的用戶,需要登記,包括姓名和信用卡等信息。

          三類請(qǐng)求的業(yè)務(wù)處理過(guò)程,被分為兩個(gè)階段,
          1. 運(yùn)行于緩存中的任務(wù)隊(duì)列。設(shè)置隊(duì)列的目的,是防止處理過(guò)程耗時(shí)太長(zhǎng),導(dǎo)致大量用戶請(qǐng)求擁塞于門戶服務(wù)器,導(dǎo)致系統(tǒng)癱瘓。
          2. 業(yè)務(wù)處理處理器,對(duì)于每一類業(yè)務(wù),分別有一群業(yè)務(wù)服務(wù)器。不同業(yè)務(wù)的處理流程,各不相同。
          圖二。12306.cn 網(wǎng)站查詢和訂票業(yè)務(wù)流程設(shè)想圖。
          Courtesy http://i879.photobucket.com/albums/ab351/kan_deng/12306-1.png
          圖二描述了查詢和訂票,兩個(gè)業(yè)務(wù)的處理流程。登記業(yè)務(wù)流程從略。 查詢的業(yè)務(wù)流程,參見(jiàn)圖二上半部,分五步。
          這里有兩個(gè)問(wèn)題需要注意,
          1. 用戶發(fā)出請(qǐng)求后,經(jīng)過(guò)短暫的等待時(shí)間,能夠迅速看到結(jié)果。平均等待時(shí)間不能超過(guò) 1 秒。
          2. 影響整個(gè)查詢速度的關(guān)鍵,是“查詢服務(wù)器”的設(shè)計(jì)。

          查詢?nèi)蝿?wù)可以進(jìn)一步細(xì)化,大致分成三種。
          1. 查詢車次和時(shí)間表,這是靜態(tài)內(nèi)容,很少與數(shù)據(jù)庫(kù)交互,數(shù)據(jù)量也不大,可以緩存在內(nèi)存中。 車次和時(shí)間表的數(shù)據(jù)結(jié)構(gòu),不妨采用 Key-Value 的方式,開(kāi)發(fā)簡(jiǎn)單,使用效率高。Key-Value 的具體實(shí)現(xiàn)有很多產(chǎn)品,[5] 建議使用 Redis。 這些是技術(shù)細(xì)節(jié),不妨通過(guò)對(duì)比實(shí)驗(yàn),針對(duì)火車票訂票系統(tǒng)的實(shí)際流量,以及峰值波動(dòng),確定哪一個(gè)產(chǎn)品最合適。
          2. 查詢某一班次的剩余車票,這需要調(diào)用數(shù)據(jù)庫(kù)中不斷更新的數(shù)據(jù)。 [5] 建議把剩余車票只分為兩種,“有”或“無(wú)”,這樣減少調(diào)用訪問(wèn)數(shù)據(jù)庫(kù)的次數(shù),降低數(shù)據(jù)庫(kù)的壓力。但是這樣做,不一定能夠滿足用戶的需求,說(shuō)不定會(huì)招致網(wǎng)友的批評(píng)譏諷。 [4] 建議在訂票隊(duì)列中,增加測(cè)算訂票隊(duì)列長(zhǎng)度的功能,根據(jù)訂票隊(duì)列長(zhǎng)度以及隊(duì)列中每個(gè)請(qǐng)求的購(gòu)票數(shù)量,可以計(jì)算出每個(gè)車次的剩余座位。如果 12306.cn 網(wǎng)站只有一個(gè)后臺(tái)系統(tǒng),這個(gè)辦法行之有效。 但是假如 12306.cn 網(wǎng)站采用分布式結(jié)構(gòu),每個(gè)鐵路分局設(shè)有子系統(tǒng),分別管理各個(gè)鐵路分局轄區(qū)內(nèi)的各個(gè)車次。在分布式系統(tǒng)下,這個(gè)辦法面臨任務(wù)轉(zhuǎn)發(fā)的麻煩。不僅開(kāi)發(fā)工作量大,而且會(huì)延長(zhǎng)查詢流程處理時(shí)間,導(dǎo)致用戶長(zhǎng)久等待。
          3. 已經(jīng)下單的用戶,查詢是否已經(jīng)成功地訂上票。 每個(gè)用戶通常只關(guān)心自己訂的票。如果把每個(gè)用戶訂購(gòu)的車票的所有內(nèi)容,都緩存在內(nèi)存里,不僅非常耗用內(nèi)存空間,內(nèi)存空間使用效率低下,更嚴(yán)重的問(wèn)題是,訪問(wèn)數(shù)據(jù)庫(kù)過(guò)于頻繁,數(shù)據(jù)量大,增大數(shù)據(jù)庫(kù)的壓力。

          解決上述分布式同步,以及數(shù)據(jù)庫(kù)壓力的兩個(gè)問(wèn)題,不妨從訂票的流程設(shè)計(jì)和數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)入手。
          假如有個(gè)北京用戶在網(wǎng)上訂購(gòu)了一套聯(lián)票,途經(jīng)北京鐵路局和鄭州鐵路局轄區(qū)的兩個(gè)車次。
          用戶從北京上網(wǎng),由北京鐵路局的子系統(tǒng),處理他的請(qǐng)求。
          北京鐵路局的訂票服務(wù)器把他的請(qǐng)求一分為二,北京鐵路局的車次的訂票,在北京子系統(tǒng)完成,鄭州鐵路局的車次在鄭州子系統(tǒng)完成。
          每個(gè)子系統(tǒng)處理四種 Key-Value 數(shù)據(jù)組。
          1. 用戶ID:多個(gè) (訂單ID)s。
          2. 訂單ID:多個(gè) (訂票結(jié)果ID)s。
          3. 訂票結(jié)果ID: 一個(gè) (用戶ID,車次ID)。
          4. 車次ID:一個(gè)(日期),多個(gè) (座位,用戶ID)。
          北京訂票服務(wù)器完成訂票后,把上述四個(gè)數(shù)據(jù)組,寫入北京子系統(tǒng)的數(shù)據(jù)庫(kù),同時(shí)緩存進(jìn)北京的查詢服務(wù)器,參見(jiàn)圖二下半部第6步和第7步。
          鄭州訂票服務(wù)器完成訂票后,把上述四個(gè)數(shù)據(jù)組,寫入鄭州子系統(tǒng)的數(shù)據(jù)庫(kù),同時(shí)緩存進(jìn)北京的查詢服務(wù)器,而不是鄭州的服務(wù)器。 讓訂票服務(wù)器把訂票數(shù)據(jù),同時(shí)寫入數(shù)據(jù)庫(kù)和查詢服務(wù)器的緩存,目的是讓數(shù)據(jù)庫(kù)永久保留訂票記錄,而讓大多數(shù)查詢,只訪問(wèn)緩存,降低數(shù)據(jù)庫(kù)的壓力。
          北京用戶的訂票數(shù)據(jù),只緩存在北京的查詢服務(wù)器,不跨域緩存,從而降低緩存空間的占用,和同步的麻煩。這樣做,有個(gè)前提假設(shè),查詢用戶與訂票用戶,基本上是同一個(gè)人,而且從同一個(gè)城市上網(wǎng)。
           但是這里有個(gè)缺陷,某用戶在北京上網(wǎng)訂了票。過(guò)了幾天,他在北京上網(wǎng),輸入用戶ID和密碼后,就會(huì)看到他訂購(gòu)的所有車票??墒怯诌^(guò)了幾天,他去了鄭州,從鄭州上網(wǎng),同樣輸入用戶ID和密碼,卻看不到他訂購(gòu)的所有車票。
           解決這個(gè)缺陷的辦法并不麻煩,在用戶查詢訂票信息時(shí),需要注明訂票地點(diǎn),系統(tǒng)根據(jù)訂票地點(diǎn),把查詢請(qǐng)求轉(zhuǎn)發(fā)到相應(yīng)區(qū)域的子系統(tǒng)。 另外,每次訂票的時(shí)候,網(wǎng)站會(huì)給他的手機(jī)發(fā)送短信,提供訂票信息,參見(jiàn)圖二下半部第8步和第9步。

          以上是一個(gè)初步設(shè)計(jì),還有不少細(xì)節(jié)需要完善,例如防火墻如何布置等等。
          這個(gè)設(shè)計(jì)不僅適用于單一的集中式部署,而且也適合分布式部署。
          或許有讀者會(huì)問(wèn),為什么沒(méi)有用到云計(jì)算?其實(shí)上述架構(gòu)設(shè)計(jì),為將來(lái)向云計(jì)算演變,留下了伏筆。
          在上述架構(gòu)設(shè)計(jì)中,我們假定每個(gè)環(huán)節(jié)需要用多少服務(wù)器,需要多大容量的數(shù)據(jù)庫(kù),預(yù)先都已經(jīng)規(guī)劃好。
          但是假如事先的規(guī)劃,低于實(shí)際承受的流量和數(shù)據(jù)量,那么系統(tǒng)就會(huì)崩潰。
          所以,事先的規(guī)劃,只能以峰值為基準(zhǔn)設(shè)立。 但是峰值將會(huì)是多少?
          事先難以確定。即便能夠確定峰值,然后以峰值為基準(zhǔn),規(guī)劃系統(tǒng)的能力,那么春運(yùn)過(guò)后,就會(huì)有大量資源冗余,造成資源浪費(fèi)? 如何既能抗洪,又不造成資源浪費(fèi)?解決方案是云計(jì)算,而且目前看來(lái),除了云計(jì)算,沒(méi)有別的辦法。

          Reference,
          [1] 海量事務(wù)高速處理系統(tǒng)。 http://www.douban.com/note/195179318/
          [2] 去你*的‘海量事務(wù)高速處理系統(tǒng)’。 http://weibo.com/1577826897/y0jGYcZfW
          [3] 火車訂票系統(tǒng)的設(shè)想。 http://weibo.com/1570303725/y0l9Y2mwE
          [4] 鐵路訂票系統(tǒng)的簡(jiǎn)單設(shè)計(jì)。 http://blog.codingnow.com/2012/01/ticket_queue.html
          [5] 鐵路訂票網(wǎng)站個(gè)人的設(shè)計(jì)淺見(jiàn)。 http://hi.baidu.com/caoz/blog/item/f4f1d7caee09b558f21fe780.html
          題圖來(lái)自 Designyoutrust

          posted on 2012-01-13 13:39 paulwong 閱讀(325) 評(píng)論(0)  編輯  收藏 所屬分類: J2EE 、分布式 、性能優(yōu)化

          主站蜘蛛池模板: 井陉县| 潜山县| 申扎县| 朔州市| 桐城市| 新巴尔虎左旗| 广州市| 安国市| 永定县| 共和县| 洮南市| 沂南县| 富顺县| 谢通门县| 寻甸| 游戏| 娱乐| 文化| 海淀区| 大埔区| 日土县| 罗城| 苏尼特左旗| 金昌市| 金阳县| 炎陵县| 罗源县| 景东| 丹棱县| 南安市| 吴堡县| 长垣县| 杂多县| 绥化市| 彰化县| 天津市| 瓦房店市| 云阳县| 临猗县| 古田县| 罗田县|