了解一件事情是怎么做的一個正確的方式是看看它在現(xiàn)實中是怎么做的。軟件工業(yè)一直以來都在為"很多idea僅僅在理論上說說"所困惑。與此同時,軟件廠商不斷地把這些idea作為最佳實踐推銷給大家。
?????? ?很少的軟件開發(fā)者親眼目睹過大規(guī)模可擴展的架構(gòu)這一領(lǐng)域。幸運的是,有時我們可以看到和聽到關(guān)于這方面公開發(fā)表的資料。我讀過一些好的資料關(guān)于google的硬件基礎(chǔ)設(shè)施的設(shè)計以及yahoo的頁面渲染專利。現(xiàn)在,另一個互連網(wǎng)的巨人,eBay,給我們提供了其架構(gòu)的一些資料(譯者注:指的是"一天十億次的訪問-采用Core J2EE Pattern架構(gòu)的J2EE 系統(tǒng)"這篇文章)。
??????? 這篇文章提供了很多信息。然而,我們將只對那些獨特的和我感興趣的那部分進行評論。
??????? 給我留下深刻印象是eBay站點的99.92%的可用性和380M page的頁面數(shù)據(jù)。除此之外,每周近3萬行代碼的改動,清楚明白地告訴我們ebay的java代碼的高度擴展性。
??????? eBay使用J2EE技術(shù)是如何做到這些的。eBay可擴展性的部分如下:
?
????????????? Judicious use of server-side state
????????????? No server affinity
????????????? Functional server pools
????????????? Horizontal and vertical database partitioning

??????? eBay取得數(shù)據(jù)訪問的線性擴展的做法是非常讓人感興趣的。他們提到使用"定制的O-R mapping" 來支持本地Cache和全局Cache、lazy loading, fetch sets (deep and shallow)以及讀取和提交更新的子集。 而且,他們只使用bean管理的事務(wù)以及使用數(shù)據(jù)庫的自動提交和O-R mapping來route不同的數(shù)據(jù)源.
?????? 有幾個事情是非常令人吃驚的。第一,完全不使用Entity Beans,只使用他自己的O-R mapping工具(Hibernate anyone?)。 第二、基于Use-Case的應(yīng)用服務(wù)器劃分。第三、數(shù)據(jù)庫的劃分也是基于Use-Case。最后是系統(tǒng)的無狀態(tài)本性以及明顯不使用集群技術(shù)。

?????? 下面是關(guān)于服務(wù)器狀態(tài)的引用:
?????? 基本上我們沒有真正地使用server-side state。我們可能使用它,但現(xiàn)在我們并沒有找到使用它的理由。....。如果需要狀態(tài)化的話,我們把狀態(tài)放到數(shù)據(jù)庫中;需要的時候我們再從數(shù)據(jù)庫中取。我們不必使用集群。也就不用為集群做任何工作。

??????? 總之,你自己不必為架構(gòu)一臺有狀態(tài)的服務(wù)器所困擾,更進一步,忘掉集群,你不需要它。現(xiàn)在看看功能劃分:
?
?????? 我們有一組或者一批機器,上面運行的應(yīng)用是某個具體的use case,比如搜索功能有他們自己的服務(wù)器群,我們可以采用不同的調(diào)優(yōu)策略,原因是瀏覽商品這個基本上是只讀的用例和賣一件商品這個讀寫的用例在執(zhí)行的時候是不同。在過去四五年我們一直采用水平數(shù)據(jù)庫劃分達到我們需要的可用性和線性擴展性。

??????? 總之,不要把你的應(yīng)用和數(shù)據(jù)庫放在一個giant machine,僅僅使用servers pools,每個pools對應(yīng)一個Use Case. 聽起來是否類似Google的策略。

??????? 下面是關(guān)于水平劃分的一些介紹:
???????? 基于內(nèi)容的路由可以實現(xiàn)系統(tǒng)的水平線性擴展。所以,想象一下,如果eBay某天擁有6000萬種商品,我們不必把這些數(shù)據(jù)存儲到一臺超級Sun服務(wù)器上。.....也許我們可以把這些數(shù)據(jù)庫放到許多臺Sun服務(wù)器,但是我們怎么取到我們需要的數(shù)據(jù)呢?eBay提出了基于內(nèi)容路由的方法. 這種方法通過一定的規(guī)則,從20臺物理服務(wù)器中找到我需要的數(shù)據(jù)。更cool的事情是這里還定義了failover的策略。

??????? 最后,下面一句話描述了未來采用更加松散耦合的架構(gòu):
?
?????? 使用消息系統(tǒng)來耦合不同的Use Case是我們研究的內(nèi)容。

??????? 是不是覺得很奇怪,最初這篇文章是介紹J2EE設(shè)計模式的?關(guān)鍵的線性擴展的思想幾乎和Patterns無關(guān)。是的,eBay采用設(shè)計模式組織他們的代碼。然而過分強調(diào)設(shè)計模式將失去對整體的把握。eBay架構(gòu)關(guān)鍵的思想是無狀態(tài)的設(shè)計,使用靈活的,高度優(yōu)化的 OR-mapping 層以及服務(wù)器基于use cases劃分。設(shè)計模式是好的,然而不能期望它使應(yīng)用具有線性擴展性。

??????? 總之,eBay和Google的例子表明以Use-Case為基礎(chǔ)組成的服務(wù)器pools的架構(gòu)比幾個大型計算機證明是具有更好線性擴展性的和可用性。當(dāng)然,廠商害怕聽到這樣的結(jié)論。然而,部署這么多服務(wù)器的最大麻煩是如何管理好他們。-)


?

我的總結(jié):
??????? ?eBay
采用設(shè)計模式達到eBay架構(gòu)的分層,各層(表示層、商業(yè)邏輯層、數(shù)據(jù)訪問層)之間松散耦合,職責(zé)明確,分層提高了代碼的擴展性和程序開發(fā)的效率。
??????? ?eBay
采用無狀態(tài)的設(shè)計,靈活的、高度優(yōu)化的 OR-mapping 層以及服務(wù)器基于use cases劃分,達到應(yīng)用之間的松散耦合,提高系統(tǒng)的線性擴展性。
???????
為什么要求系統(tǒng)具有可線性擴展,目的就是當(dāng)網(wǎng)站的訪問量上升的時候,我們可以不用改動系統(tǒng)的任何代碼,僅僅通過增加服務(wù)器就可以提高整個網(wǎng)站的支撐量。