分塊云計算簡介
這篇文章沒有什么新奇觀點,只是將我的思考與觀察做一個概括。
多年忽視分塊
即使過了16年,我依然清楚記得[Booch OOAD]書中討論如何使用分層與分塊(有的讀者可能更偏好"模塊"這個同義詞)。那時候我開班講授一門面向對象分析與設計的課程,這本書是教材。我感覺討論分層很容易,因為當時接觸甚多(后來仍然深受影響,下一節會談及),但要討論分塊就有點難。
在我參與的實際項目中,我們確實一直采取分塊的做法,但講授的時候很難用短小的例子示范分塊。而且就我記憶所及,我們采取分塊只是出于技術上的限制,并不像分層那樣是自然而然地發生的。.
分塊沒能“物盡其用”的感覺一直伴隨著我,我也就聽之任之。
濫用分層
2001年寫第一本書[Nilsson NED]的時候,我對分層的盲目溺愛到達頂峰。圖1的分層示意圖已經是簡化過的版本。
圖1. 過去的典型分層(簡化版本)
圖1可見,中間層包括了Fa?ade層、業務邏輯層和數據訪問層。在數據層還有公共存儲過程(sproc)層、私有存儲過程層,有時候數據表之上還有視圖層……(UI部分也是分層的,可想而知……)。
我把這種分層方案稱為我的“默認架構”,顧名思義,我每次著手新項目都以此作為出發點。當然具體的架構形態隨著時間會有所變化,但重點是我先入為主地認為項目都離不開這種嚴格的分層方案。 如此一來,我不用再拘泥嚴格的分層方案,轉而把精力集中于尋找恰當的分塊。又由于整個解決方案被分為若干小塊,從而每一個分塊的分層形式可以更加靈活,因為規模更小了。
按技術拆分團隊
寫上面一節的時候,我想起了2005年在挪威Lillehammer舉行的軟件架構研討會[Fowler LayeringPrinciples]。當時我們在會上討論如何把大的團隊拆分成若干小團隊。
無論那次會議之前或之后,我都有拆分團隊的經驗,多次拆分中既有按技術拆分的,也有按功能拆分的。我尤其記得一個項目,對其中一名團隊成員來說,按功能拆分是失敗的,因為他沒有什么經驗,所以幾乎每一個方面他都不得不苦苦掙扎。.
在另一個項目中,按技術拆分看起來非常成功,不過那個項目的成員都很有經驗。即使在這個成功項目里,也有很多情況如果按功能拆分會取得更高的效率。比如跨單元的小改動,牽涉到的人可以更少。
總而言之,我偏向按功能拆分團隊。每個人肯定有自己特別擅長的部分,但如果不用協調及等待其他人完成相應的工作,那么大部分工作都可以更快地完成。
企業領域模型
前些年很流行建立整個企業“一統天下”的數據模型。背后的想法是如果一朝找到并描述出這樣的數據模型,就能從中創造出巨大的業務價值。于是傳達給業務人員的是這樣的信息:
“現在給我們兩年時間不受干擾,到時候我們會交給你一個定義好的模型,你想要的一切都能不費吹灰之力就創造出來。”
依我之見,“企業數據模型”是大大失敗了。原因肯定不少,但下面這幾點可能在最重要之列:
即便是中等規模的企業,數據模型的規模也過于龐大。
數據模型試圖用靜態的方法描繪一個動態的目標。而且描繪一個龐大的目標比小的目標要困難得多。 大模型或多或少要作一般化的處理,并因此失去上下文信息。
我個人強烈相信大的任務要一口一口地啃,而上下文是王道。
A前面說過,我認為建立企業數據模型的嘗試常常以失敗告終。現在我又發現一種有點諷刺的情形——還有項目幾乎在重復同樣的嘗試,只不過這一次換成了“企業領域模型”。論據沒變,我想結果和造成結果的原因也不會變……
公平來說,更常見的情況倒不是真的追逐“企業領域模型”,而是想建立單一的大型領域模型。此外,團隊不時發現有需要切分大的領域模型,但又發現不容易找到滿意的方案。
無論如何,我都強烈建議當領域模型出現增大跡象的時候,將它分塊。還有別忘了模型是有上下文的。
很有趣,我還聽聞一些非常大的SOA項目采取的第一個步驟就是打算建立一套“企業文檔模型”。它會比企業數據/領域模型更成功嗎?要是打賭的話,我寧愿下注在另一邊。
整合數據庫
就算有意避免巨型的單一領域模型,把模型隔離成幾個部分,每一個部分還是有可能膨脹到相當規模。發生這種情況的時候,往往會發現數據庫并沒有分塊。各個領域模型置于同一個數據庫之上,也就是共用一個整合的數據庫,見圖3。
圖3. 分塊的領域模型,使用整合數據庫
把多個領域模型置于單一數據庫之上,只是整合數據庫的其中一種情形。實際上跟多個獨立應用共享同一個數據庫是一樣的。類似情況可謂屢見不鮮。
很不幸這樣的安排給維護造成了極大的負擔。任何影響到數據庫Schema的改動都必須同步修改相應Schema的所有消費者。消費者越多,情況越糟。往往造成改動被限制到最低程度,很可能進而導致從代碼中榨取的業務價值大大減少。
大膽地說一句,如今在我眼中,整合數據庫是一種反模式。啊,總算說出來了,感覺真好。
那么,有什么別的辦法呢?我認為領域模型的分塊應該一直延續到數據庫,讓數據庫也遵循同樣的分塊方案。這種與整合數據庫[Fowler IntegrationDatabase]相反的模式稱為單應用數據庫[Fowler ApplicationDatabase],見圖4。
圖4. 分塊的領域模型,使用各自的單應用數據庫
分塊之間的通信是通過領域模型之上的服務完成的,不允許抄捷徑直接訪問其他領域模型的應用數據庫。這意味著可以(也通常會)有效地將不同的應用數據庫部署到不同的服務器上(或者部署到云中)。
一般認為報表是整合數據庫的優勢所在。要是換一種方式去處理報表,可以把它看成一個獨立的應用,有著自己的數據存儲。數據從其他分塊搜集而來。其中一種辦法是將每個分塊都看作一個提供事件源的應用[Fowler Events],讓那些事件源都吐出報表應用感興趣的事件就可以了。
順便一提,上面的討論令我記起曾經為ADDDP[Nilsson ADDDP]寫過一段文字[Nilsson Bricks](不過最終沒有放進書里),介紹另一種應用數據庫的用法。不過當時寫作的重點落在性能,而非可維護性。文中我介紹了如何根據系統不同部分的特點,讓系統發揮最大的功效。
再順便一提,一定要讀一讀Greg Young寫的DDDD系列文章[Greg Young],他的精彩作品也可以歸到這個主題之下。他建議嚴格切分讀和寫,籍此取得非常高的可伸縮性等等成效。
整合的UI
論點其實差不多,只不過用到UI上沒有整合數據庫vs.應用數據庫那么有力。與其用一個UI套上幾個服務,何不讓每個服務都有自己的UI,然后將不同的UI用一個UI容器框架集成起來?見圖5。
圖5. UI也分塊
這樣一來,某個分塊的開發者可以全方位地處理問題,從UI一直到存儲,不必與其它團隊同步。對實際生產率的潛在影響是巨大的。
巨型的團隊
經常有人向我們求助,抱怨說他們100人的大團隊沒辦法達到期望的生產效率。
每一次,我都得到同樣的結論。不要那樣做!100名開發者在同一個團隊里,太可怕了,失敗風險太大了。即使你再加20個人!
雖然已經出版了30年,讀過《人月神話》[Brooks MMM]的人還是少得出奇。真糟糕。(書名“人月神話”的意思是,向一個進度落后的項目增加更多開發者,只會讓它更落后。書里還闡述了很多重要的思想。)
所以,就算退一步說你真的有一個規模龐大的問題要解決,你也真的需要100名開發者。請一定要小心謹慎地將大團隊分成若干個小規模的、盡可能相互隔離的團隊,以便每個團隊能夠全速運行。
但是當你把大團隊分成比如說100個新團隊的時候,顯然不會因此就消滅了復雜性。例子里面分成10-20個團隊比只有1個團隊好,并不表示分成100個會更好。請注意平衡。
SOA與松散耦合
說到平衡,兩年前我曾經很不理解SOA的一些說法,還寫了博客帖子[Nilsson SOA-Qs]請教答案。
我不理解的其中一點是為什么要極端的細粒度。為什么不用“定界上下文(Bounded Context)” [Evans DDD]的思維來看待服務呢,為什么需要粒度細到只有一行代碼的服務……
Jim Webber在一篇文章里[Webber Anemic Service Model]討論過這個問題,我認為他說得很有道理。對松散耦合的關注成了唯一的決定因素,以至于忘了搭配上它的好朋友——高內聚,才導致出現令我困惑不解的奇怪說法。
所以,我把前面討論的分塊看作是“做對了的SOA”。
強迫一種風格
最初我把標題定為“強迫一種信仰”,但又顧慮到Google帶來的很多人會失望。我在這里談的風格/信仰,是指我們當中有很多人喜歡思考和討論TDD、DDD、BDD、模式、重構、干凈的代碼等等。但世上還有更多開發者并不同意我們所說的是“唯一的道路”。
有時候會采取的解決辦法是完全不理會實際情況,強迫所有的開發者都用同一種風格。會發生什么事呢?我猜下面這幾種情況會很常見:
有的開發者會非常低效。
低效的開發者還會很不開心。
最后整個團隊圍繞的風格是所有成員的“最小公分母”。
于是當初贊同強迫推行那種風格的開發者,現在也變得低效和不開心。
能保持一致是好的,但不能不惜代價去保持一致。實際上我覺得很多時候讓不同的分塊用不同的風格開發,反而有好處。不同開發者之間的技能差異是其中一個原因。還有另一個經常被忽視的原因,不同的分塊當然是有差異的,所以相應地采取不同的風格反而有利。比如有的分塊從領域模型方式中肯定得不到什么好處,那么不采取領域模型的路線也沒關系,實際上也建議不要那么做!
即使放寬了對分塊內部的約束,你還是可以(也應該)對外部表現設立嚴格的要求,比如要保證自動化測試成功。
我意識到以上做法違反了集體代碼所有制的原則,因為人們都圈在自己的分塊里。在分塊內部,(如果該分塊選擇了集體所有的風格)肯定是代碼集體所有的。
對了,在單個分塊內,我認為應該強迫一種風格。
變化率差異
這件事情你可能覺得顯而易見,不過我還是要特別指出來:不同分塊的變化率可能有極大的差異。在數據庫驅動的項目里,有句話在項目前期的會議上經常聽到,我也常常拿來開玩笑:
“我們已經定好了數據庫Schema,現在可以開始干活了!”
沒有取笑誰的意思,我自己也說過這樣的話。
雖然我有些猶豫要不要說出來,不過有的分塊也許的確能用那樣的方式取得很好的結果,定好數據庫Schema,以后就不再改了。
而同時其他的分塊可以采用DDD項目的典型風格:
“好吧,我們現在了解得還不深,不過讓我們先按目前的理解來做,隨著我們了解加深,領域模型可以天天改,也一定會天天改!”
現在兩種風格可以愉快地并存。以前肯定也有并存的情況,只不過現在明確了界限,成功機會提高了。
名字的來歷
有人說任何值得討論的事物都應該賦予一個名稱,我當然不希望這種架構風格僅僅因為沒有名稱就失去討論的資格。
那么“分塊云計算(Chunk Cloud Computing)”是個好名稱嗎?爭議肯定是少不了的,先放在一邊,聽我說一下來歷吧。
在本屆歐洲軟件架構研討會上,Christoffer Skjoldborg提了一個叫做“Chunk Cloud”的論題。“Chunk”就是一小片(分塊),“Cloud”是現在的炒作題材。他的描述很接近我近來觀察到的一種應用架構方式。(本文就是努力在描述這種架構方式。“強迫一種風格”小節尤其得自Chris的啟發。)Chris描述的時候說得有點極端,不過我想主要是為了讓他的觀點流傳開。
最后的“Computing”是研討會上Nicklas Andersson
最佳實踐?
不知道你怎么樣,我聽到“最佳實踐”的時候會警覺起來。可能是由于那些與Dreyfus模型[Dreyfus model of skill acquisition]相關的討論,還由于見識到一些無視上下文的“最佳實踐”……
我不認為“塊云計算”是一種最佳實踐。我只認為它是一種架構風格,而我經常發現適用這種風格的場合。但別忘了,要看情況。
新問題?
當然有了!可是你不覺得老問題沒意思么?我知道這種風格有很多新問題,以后還會冒出更多(肯定的)。最多人提出來的兩個問題是同樣的數據出現在好幾個地方,以及不同的分塊之間有數據不一致的風險。這兩個問題都必須解決,但請容我放到另一篇文章里。
還有一個經常提出的問題是“怎么做”,尤其是怎么將領域模型拆成幾個小塊。我會再找時間詳談。
更進一步的觀察對此方向是肯定還是否定?
穩妥地說,兩方面的觀察(及觀點)都有,我也期盼著看到您的想法!
評論
查看更多