系統(tǒng)業(yè)務示例
鐵道部12306網(wǎng)站遭到全國人民的批評材原。它確實存在一些問題窿侈,但這些看似簡單的問題背后涉及復雜的系統(tǒng)架構(gòu)設計念秧。這些設計最終服務于業(yè)務需求,也就是說聊闯,12306的責任是服務于所有乘客的需求工猜,程序員設計的程序?qū)⒎沼?2306,所有用戶體驗最終歸結(jié)為服務意識菱蔬。我們來看看12306的業(yè)務篷帅,12306需要支持海量并發(fā)查詢史侣,即海量用戶同時查詢時間、查詢公交時刻魏身、查詢座位惊橱、查詢臥鋪。此外箭昵,相應的排序過程伴隨著大量并發(fā)數(shù)據(jù)庫操作税朴。
據(jù)說,淘寶在光棍節(jié)只有幾百萬用戶家制,而在春運高峰期間購買火車票是一項全國性的活動正林,一瞬間有數(shù)千萬甚至數(shù)億人訪問該網(wǎng)站。據(jù)說12306的峰值訪問量為10億Pv颤殴,這些訪問主要集中在上午8點到10點之間觅廓,峰值時每秒的Pv達到數(shù)千萬。
https://pan.baidu.com/s/1baB7P9voyQyOH0FLFmW5wA?pwd=23se?
讓我們看看其他業(yè)務系統(tǒng)涵但。奧運會期間的票務系統(tǒng)采用抽簽的方式杈绸。這樣的商業(yè)設計使系統(tǒng)擺脫了先到先得的搶購需求。由于是事后抽簽矮瘟,只負責提前收集信息瞳脓,不需要保證數(shù)據(jù)的一致性。因此不需要高強度和鎖7芥永,通過水平擴展很容易克服性能瓶頸篡殷。例如钝吮,B2C不要求用戶實時處理訂單埋涧。它不要求用戶在收到訂單后立即收到通知。通過這種方式奇瘦,它不需要用戶實時處理訂單棘催。換句話說,高并發(fā)要求下的數(shù)據(jù)一致性不僅是性能瓶頸耳标,也是一般意義上的技術(shù)難點之一醇坝。
如前所述,在高并發(fā)的情況下次坡,很難實現(xiàn)數(shù)據(jù)的高實時一致性呼猪。對于一個網(wǎng)站來說,并發(fā)瀏覽網(wǎng)頁造成的高負載比較容易處理砸琅,并發(fā)查詢的高負載也可以處理宋距,但實時下單是最難處理的,因為下單需要訪問當前庫存症脂。對于12306網(wǎng)站來說谚赎,庫存是指火車票的庫存淫僻。由于這是一個全國性的聯(lián)網(wǎng)系統(tǒng),可以預見壶唤,很難保持庫存數(shù)據(jù)的一致性雳灵。據(jù)說,蘋果公司的CEO庫克之所以能接替喬幫的領(lǐng)導闸盔,是因為他處理了庫存問題悯辙。目前很多B2C網(wǎng)站采用異步方式下單,可以避免數(shù)據(jù)一致性高的要求蕾殴。
淘寶模式相對于傳統(tǒng)B2C網(wǎng)站有一個優(yōu)勢笑撞,即不需要查詢庫存。B2C網(wǎng)站有自己的倉庫钓觉。在每次下訂單之前茴肥,您需要確定離客戶最近的倉庫是否有庫存。累積后這個計算量會很大荡灾。例如瓤狐,如果你在上海買一本書,上海附近的倉庫缺貨批幌。我們需要先計算哪個倉庫離上海最近础锐,有這本書由于自身的商業(yè)模式,淘寶不需要實時查看庫存荧缘,但更容易進行業(yè)績拓展皆警。
事實上,我們可以通過nginx每秒處理100000個靜態(tài)請求截粗。只要我們有足夠的網(wǎng)絡帶寬和磁盤IO信姓,服務器就具有強大的并發(fā)計算能力,可以輕松處理100000個并發(fā)連接绸罗。但是意推,如果我們引入大量的業(yè)務邏輯,就不是簡單的訪問問題了珊蟀,解決方案將變成一個浮動云菊值。
除了業(yè)務需求和程序運行模式外,程序設計本身還需要考慮很多因素育灸,如基礎編程技術(shù)腻窒、系統(tǒng)架構(gòu)、網(wǎng)絡技術(shù)磅崭、操作系統(tǒng)儿子、硬件服務器等。計算機專家非常重視問題解決中簡單性的價值绽诚。UNIX的先驅(qū)Ken Thompson曾經(jīng)說過一句非常著名的話:“我丟棄了1000行代碼的那一天是我工作效率最高的一天典徊『技澹”對于任何需要持續(xù)支持和維護的軟件項目來說,這都是一個值得實現(xiàn)的目標卒落。早期LISP貢獻者Paul Graham L4甚至將語言的簡單性等同于語言的能力羡铲。這種對能力的理解使我們把編寫緊湊和簡潔的代碼作為許多現(xiàn)代軟件項目的主要標準。
任何程序都可以通過重構(gòu)代碼方式去除多余的代碼或無用的占位符儡毕,例如空格也切,刪除空格后會讓代碼變得更加簡短。不過某些語言天生就善于表達腰湾,也就特別適合于簡短程序的編寫雷恃。APL語言的設計理念是利用特殊的圖形符號讓程序員用很少量的代碼就可以編寫功能強大的程序。這類程序如果實現(xiàn)得當费坊,可以很好地映射成標準的數(shù)學表達式倒槐。簡潔的語言在快速創(chuàng)建小腳本時非常高效,特別是在目的不會被簡潔所掩蓋的簡潔明確的問題域中附井。
相比于其他程序設計語言讨越,Java 語言的冗長已經(jīng)名聲在外,主要原因是由于程序開發(fā)社區(qū)中所形成的慣例永毅。在完成任務時把跨,很多情況下要更大程度地考慮描述性和控制能力。例如沼死,長期來看着逐,長變量名會讓大型代碼庫的可讀性和可維護性更強。描述性的類名通常會映射為文件名意蛀,在向已有系統(tǒng)中增加新功能時會顯得很清晰耸别。如果能夠一直堅持下去,描述性名稱可以極大簡化用于表明應用中某一-特定的功能的文本搜索浸间。實踐證明太雨,這些定義方式讓Java在大型復雜代碼庫的大規(guī)模實現(xiàn)中取得了極大的成功吟榴。
相對于傳統(tǒng)的32位虛擬機魁蒜,64 位虛擬機所具備的最大優(yōu)勢就是可以訪問大內(nèi)存。32 位虛擬機最大可用內(nèi)存空間被限定在了4GB吩翻,并且Java堆區(qū)的大小配置存在最大限制,如果是在Windows平臺下最大只能設置到1.5GB兜看,而在Linux平臺下最大也只能設置到2GB ~3GB。也就是說狭瞎,Java堆區(qū)的內(nèi)存大小設置還需要依賴于具體的操作系統(tǒng)平臺细移。
既然32位虛擬機無法滿足大內(nèi)存消耗的應用場景,那么64位虛擬機的出現(xiàn)則是順理成章的。64位虛擬機之所以能夠訪問大內(nèi)存熊锭,是因為其采用了64位的指針架構(gòu)弧轧,這也是尋址訪問大內(nèi)存的關(guān)鍵要素雪侥。