閱讀目錄:前端
最近一段時間都在作系統分析和設計工做,面對的業務是典型的重量級企業應用方向。忽然發現不少以往以爲很簡單的問題變得沒有想象的那麼容易,最大的問題就是職責如何分配。論系統架構設計的最大的問題,其實也就是職責的分配,分配的合理,實現起來就會很柔性,反之就會使架構很混亂。數據庫
軟件的生命週期大概能夠概括爲四個基本的過程,分析、設計、實現、測試,固然這僅僅是一個最爲粗略的表示而已。不一樣的方法論有着不一樣的使用這幾個過程的方式。RUP使用快速迭代的過程,在這個幾個子過程當中適當的輸出一些過程製品,每次迭代都是進行相同的分析、設計、實現、測試。而在Scrum中,不提倡輸出任何文檔形式的過程製品,也一樣有着上述幾個過程,強調以人爲中心,經過溝通來解決大部分的問題。後端
不能用好與很差來判斷哪種方法論,只能根據目前的實際狀況綜合權衡。RUP的每次迭代中有幾個關鍵的製品對系統分析、設計很重要,能夠說是很是重要,如:詞彙表、業務規則文檔、用例、領域草圖。這幾個製品對分析、設計很重要,須要從這幾個製品中提煉出設計模型最終才能落地。這主要用在業務複雜的應用系統中。而Scrum更加的輕量級,能夠用在互聯網項目中,業務不是太複雜的狀況下。架構
其實我爲何要強調軟件工程及開發方法論,是由於我最近發現,作設計實際上是創建在分析的基礎上的,可是這裏面又有不少問題。大型企業級應用,並不能經過一次性分析就能夠得出準確和所有的需求,初期階段創建的需求70%都是不許確的。因此作架構須要有分析的能力才行且是創建在適當的開發方論上的分析,何時該用RUP,何時該用Scrum,何時該用XP都頗有講究。分析與設計都須要有一個執行上下文,不一樣的上下文對分析、設計的執行有着不一樣的要求。運維
有句話我以爲對架構者來講頗有啓發:分析就是作正確的事,設計就是正確的作事。架構跟語言跟平臺關係不大,畢竟架構是設計過程當中的子過程,我想若是你的設計不合理,你用任何語言任何平臺都解決不了問題。(這裏的架構上下文指:企業應用架構不是基礎設施的系統架構)異步
進行SOA類型的架構設計就須要搞清楚SOA架構模型才行。並不能想固然的對系統進行簡單的拆分就行,須要搞清楚SOA的架構模型是怎樣的,每一塊是幹什麼用的,這樣設計由分析階段輸出的需求時才能正確的劃分職責。分佈式
若是把SOA的架構簡單的理解爲是多個子系統之間的整合其實有點太過於簡單,也沒有真正搞清楚SOA的架構模型。按照SOA的正確方法論及目標模型,其實SOA在實現架構落地上,須要考慮到對服務的組合,不斷的重用現有的服務,讓企業應用能夠逐步集成,快速實現業務的迭代。其實這就是本節要講的服務的分層,經過分層將服務按照使用類型進行分配,上層服務對下層服務的包裝,下層服務負責原子性的操做,上層服務對下層服務進行業務性的組合。工具
咱們來看具體的每一層的做用及主要職責。post
應用服務就是諸如:訂單服務、倉庫服務、銷售服務、客戶管理服務,這些服務直接對應不一樣的應用系統,直接服務這些應用系統的原子操做。訂單服務直接原子性的插入訂單,沒有任何跨其餘服務的分支邏輯。倉庫服務只管本身的倉庫邏輯。一樣其餘的應用服務只管好本身的職責,杜絕對其餘服務的調用。性能
圖1:
應用服務位於UI與後臺之間,後臺咱們能夠認爲它是一異構的系統或者是數據庫之類的。應用服務的位置位於前端與後端之間,起到相似一個服務API的做用,可是SOA中的服務還遠遠不止這一個應用服務,若是咱們的SOA架構中只有一種類型的服務,那麼這會增長咱們系統的耦合程度,由於你沒有對系統的服務進行層次的劃分,你的業務功能會直接的落到某一個應用線上的服務,繼續往下看。
組合服務是對應用服務的一個組合,根據實際項目的規模大小,不必定非要進行物理的隔離,在代碼層面的服務化也是能夠的,在未來的某一天有必要的狀況下再進行物理的拆分,畢竟物理的拆分有着嚴重的成本和代價,對系統的穩定性帶來不少挑戰。因此經驗告訴咱們必要的時候在進行拆分。」分佈式系統設計的第一個原則就是儘可能不要分佈式「,這是馬丁.福勒大師說的,如今理解確實感同身受。
圖2:
組合服務對下層的應用服務進行了組合,完成了一個基本的業務動做,應用服務中是最基本的基礎性的原子性的操做。可是在複雜的業務需求下大部分業務功能都須要跨越多個應用線來完成一個最外層的企業動做。提交訂單可能須要穿過不少應用線,訂單管理、倉庫、財務等等環節。因此這裏咱們還須要一個能在最外層對組合服務進行編排的業務服務。這個編排服務能夠徹底是自動化的,經過工做流引擎進行組合自動化來完成,這對企業應用的自動化流程頗有意義。
業務服務是最外層的服務,向下編排了組合服務。業務服務位於最上層,當須要有跨越多個應用線來完成的業務,這個業務就放入業務服務中。好比提交訂單,先檢查庫存、扣減庫存(凍結庫存),而後下單,再日後通知財務,再日後通知物流等等都是一個複雜的企業服務線。這種最外層的業務邏輯若是你不進行SOA分層而後將其放入最外層的業務服務中,你把它放入任何一個應用線都會使系統調用混亂不堪。因此問題就是須要進行縱向的劃分層次。若是進行了SOA的層次劃分後就不會出現互相亂用的狀況。其實這裏能夠參考阿里的服務設計方法。(李智慧寫的一本大型互聯網架構與實踐裏面也講到了服務要劃分層次)
圖3:
當在業務服務中執行的業務邏輯時,須要跨越多個應用線來完成。這部分的邏輯也說是職責,若是不放入這個位置,放在哪一個應用線都不合適,放入哪一個應用線都會使系統調用出現混亂。其實這裏的問題就是咱們不能用一個維度來進行SOA系統的設計,原本服務就具備組合特性,因此適當的提高服務的層次是有好處的,可是應用服務和組合服務能夠在代碼層面上進行構建,而業務服務也叫編排服務是須要進行物理隔離的,畢竟考慮到系統複雜度和穩定性問題這是值得的。在排查問題,系統性能、穩定性等等方面,物理的隔離有必定的做用,畢竟業務服務原本就是來組合多個應用線的,這樣作會使整個系統架構很清晰。
進行SOA化的實施,大部分狀況下都是對現有系統進行重構後考慮的,初期企業發展階段以快速出原形爲首要目標,只有當系統出現瓶頸了纔會考慮運用SOA來解決。可是在這個時候有不少歷史包袱沒法解決,進行SOA化的重構其實成本是很高的,並且很危險,對有些複雜的邏輯說的現實點,是無能爲力的。若是均可以經過重構這個技術來解決,那咱們就太天真了。《重構—馬丁.福勒》一書講的是代碼層面的重構,跟作系統級重構兩個概念。對系統級別的重構尚未太多成熟的方法論支撐。尤爲如今新技術層出不窮的,各有優勢,能很好的運用這些技術、方法論、過程來重構大型企業級系統,難度很是大,這須要整個公司投入不少人力、資源成本。回過頭來想一想,其實在前期適當考慮一下仍是有必要的,這樣能夠減小後期不少技術債務。
這裏我只總結我在分析、設計公司某一塊業務系統的時候對其進行SOA化的重構思路。重構原本就是一個不斷迭代的過程,不能夠跨大步。經過不少腳手架支撐,讓系統慢慢的過分到新的SOA架構下,既然要實施SOA架構,那麼很重要的一點就是對遷移的業務邏輯適當的歸類,什麼業務邏輯該放入「業務服務」中,什麼邏輯該在代碼層面上放入「組合服務」中,對基本的操做有如何放入代碼層面的「應用服務」中。
在進行系統拆分的時候,對當先後端的調用都進行適當的規劃,將其分爲兩類,一類是應用服務,一類是組合服務,這兩個服務是能夠在代碼層面上進行抽象。重點是那些調用其餘系統的地方,須要將其放入業務服務中,這塊邏輯比較複雜,難以抽取,須要適當的結合」數據落地「的思路來綜合考慮。有時候把一部分數據落入本地能夠提高系統的總體簡潔度和穩定性,可是要考慮數據的一個生命週期性質。
在遷移的過程當中可能還會有一些新的功能並行開發的,既有新的邏輯須要放入新的SOA服務中,也會有遷移過來的邏輯,這兩個過程同時進行其實很痛苦,儘可能避免這樣同時進行,可是現實是根本不可能,正常都是一塊兒並行推動。若是這兩個過程是同一組團隊負責其實還好,畢竟對這塊的代碼、業務都比較瞭解。
這一節目的是想強調對如今系統進行遷移的時候要考慮服務的層次,不要只進行一個簡單的搬移代碼,這個時候是一個對代碼進行重構的好機會,該劃分層次的要劃分層次,該讀寫分離的要讀寫分離,要重點考慮那些「業務服務」,須要跨越多個應用線的邏輯。
順便說一下,還有一個重點就是遷移的時候還要考慮數據存儲方面的遷移,光代碼層面的遷移只是第一步,第二步還須要進行數據層面的遷移。固然這兩個大的步驟都是要經過不少次迭代完成,而且仍是一個對業務、代碼進行很好梳理和整理的好機會。
在將系統進行服務化的時候要考慮服務層,若是當前沒有業務服務的邏輯那麼就保留服務空間,至少要清楚在服務層中有這麼一個空間是要預留的,當有其餘的應用線須要與你交互的時候能夠順利的進入到你的服務區,而不是直接到達你的應用。
作系統設計時最怕的就是職責搞錯了,這會使系統的架構忽然就複雜了,並且系統架構都是很難改變的或者壓根就沒法改變的決定。因此我對這塊引發了重視,有時候你對業務在瞭解在熟悉依然會搞錯職責,對於這塊光憑主觀的判斷是不長遠的,無發覆制、沒法傳播的,也沒法落字成文的。
對DDD我這裏就很少作介紹了,這裏要強調是GRASP。運用DDD能夠很好的幫助咱們來戰略性的觀察企業所坐立的領域,我仍是很提倡DDD在公司實施的,不說DDD中的「戰術設計」方法論,就光說它的「戰略設計」方法論仍是有很大做用的,讓咱們能夠在腦海中創建一個戰略性的模型。具體要不要進行代碼層面的落地這就看實際狀況了。並且DDD中的不少不錯的思想均可以借鑑過來,包括領域通用語言,有了領域通用語言團隊之間的溝通和交流會節省不少成本。對於新人來講,能夠很快的瞭解公司的一些大概的業務,這和「詞彙表」其實仍是有區別的。
上面說了,在劃分職責的時候不少都是經過經驗來主觀的判斷,沒有其餘的客觀證據了。那麼有沒有一個不錯的方法論或模式來指導咱們進行這類問題的解決呢,其實仍是有的,由於在國外人家這方面已經很成熟。
GRASP就是這樣的一套模式,它能夠幫助咱們進行客觀的設計職責。到底該把這塊數據放入哪一個應用中,到底該把這個邏輯放入哪一個服務中,都有指導,包括對對象層面的設計依然能夠。咱們可能對「信息專家模式」都有了解,可是以往咱們可能都只把它用在對象設計上,而沒有提高一個系統層面中考慮。那是由於咱們以往可能沒有遇見很複雜的職責分配場景,只有當出現問題時咱們才能真正領會某個東西的好壞。
DDD只有結合GRASP才能客觀準確的方配某個領域的職責,無論是戰略設計層面仍是戰術設計層面,都是一個很好的平衡標準,不會因爲技術人員主觀的興趣傾向致使一個錯誤的職責分配決定,而這個錯誤的決定最終是要開發人員來買單。
傳統分佈式系統與當代的面向SOA的分佈式系統有必定區別,論概念上來說SOA是以服務爲中心,既然以服務爲中心就會有不少面向服務的設計原則。而傳統的分佈式系統沒有服務的概念,也沒有所謂的一切皆是服務的原則。而當代SOA則首要原則就要以服務爲中心,針對服務的設計又有了不少服務設計原則。
SOA對服務還進行了類型的劃分,按照服務的應用層次來分類:業務服務、組合服務、應用服務,包裝服務等。再按照管理與運維的層面來分類:控制服務、調度服務、監控服務等等。傳統的分佈式系統是沒有這些的,咱們談論的是當代SOA的分佈式系統,因此咱們強調的是以服務爲中心,以服務設計原則爲架構設計的指導要求,當代SOA是對傳統分佈式系統的一個迭代進化,不是一個時代的產物,SOA更增強調了以服務爲首要原則,已經提高到了另一個更加高級的層面。
本節咱們交流一下在當代SOA分佈式系統中的數據一致性問題,在SOA中這主要涉及兩個層面來考慮,一個是服務層面、一個數據持久化層面。再按照一致性的基本要求,能夠分爲:讀一致性、寫一致性、會話一致性、最終一致性、實時一致性等幾個維度,固然還有其餘幾個維度的一致性要求。
咱們這裏重點討論在企業應用中實施SOA時遇到的一些比較棘手的數據一致性問題和解決方案,對於剛纔提到的幾個維度的一致性要求均具備重要的參考價值。
以往包括目前不少項目仍是傾向於使用DTC來處理分佈式事務,這個方案多數適用於通常的企業應用,業務、訪問量、數據量要求都不是很高的狀況下。用DTC很方便,事務的自動傳播、事務的自動感知、事務的自動回滾和提交,這都是中央DTC幫咱們管理好了。
因爲有中央DTC的統一協調,看似好像幫咱們解決了不少咱們須要考慮的問題,可是它也是整個平臺的致命的瓶頸,一旦DTC因爲某個問題出現錯誤,並且這種錯誤都是系統層面的錯誤,不少問題咱們是無能爲力的。若是出現問題,整個應用平臺都沒法完成任何一個跨服務的業務流程,這其實很危險,你不沒法控制系統的穩定性。
這裏總結,DTC用於通常的小型企業應用,不建議用在中等規模的企業應用中,不是說這個東西很差,而是沒法控制它。
世界級SOA專家所編寫的書籍裏都提到了使用「補償」操做來完成數據的不一致性,當咱們編寫了一個服務方法A,就須要一個服務方法A1的補償接口來完成A服務的補償操做。可是真實的業務狀況下很難實施這種看起來好像很優美很柔性的設計。沒有實踐就沒有發言權,咱們公司的技術團隊就實施過這種方案,可是很不理想,這跟技術自己及技術團隊不要緊,只是咱們的平臺業務太複雜,很難去「補償」一個已經作過的操做。
這固然也要看你所面對的項目狀況,量變引發質變,若是你的各類量都上去了,這個「補償」方案不實際,並且很難在數據層面進行「補償「。總之,這不是一箇中長期的方案。
EDA簡稱」事件驅動架構「。多個系統之間經過傳播」事件「來驅動整個業務的運轉。系統之間沒有緊耦合的同步調用的操做,都是經過發出異步的「事件」來通知下一個業務環節。
可能你會有一個疑問,異步操做,是否是系統之間延遲會很長,其實不是,如今有不少成熟的消息中間件在內網內幾乎是毫秒級別的延遲,至於跨機房就看物理上的距離了。
異步操做有不少好處,這裏我就不浪費你們時間重複那些好處。使用EDA實現系統之間的一個鬆散的事務關係,要把控好項目的質量,對系統的非功能需求、BUG數等等可能會影響業務操做中斷的地方都要創建起適當的機制,讓這些問題儘早的在線下解決。好比能夠實施UnitTest、持續集成等一些敏捷的方法論。
一樣一個工具在於什麼人用,真正的工匠都是使用很樸實的工具來雕刻沒法超越的藝術品,這就是工匠情懷。最近對工匠情懷感覺愈來愈深,一直覺得本身是一個比較喜歡專的人,這是否是偏離了一個大的方向衝進了一個小衚衕,直到最近我才領悟,這實際上是」軟件工匠「的精神。可是這不表明不考慮全局,這只是一種情懷,一種態度,對於架構也是,對於代碼也是,不要認爲那些看似可有可無的問題就忽視它,帶着工匠精神鵰刻它。
參考書籍:《SOA實踐指南》、《SOA概念、技術與設計》、《精益軟件》、《UML與模式應用》、《軟件預構的藝術》