1. 程式人生 > >微服務講堂--【1】前世今生

微服務講堂--【1】前世今生

       對於微服務,有很多說法,最權威的來自於Martin Fowler  的文章。對於微服務有很多討論,有很多實踐,也遇到很多問題。包裝了很多新鮮的名詞和概念,讓人云裡霧裡。但我要說的是,太陽底下沒有新鮮事,關於微服務的理念,實際上並不是橫空出世,而是自然而然發展出的產物,歷史上已經有類似的發展脈絡。Martin Fowler同樣也說,它可以追溯到unix設計原則。

一、單程序的發展歷史

1、函式和動態庫

        在彙編時代,程式碼都是連在一起,緊湊高效卻難讀,到處goto跳轉。這時,偉大的C語言出現了,將程式碼劃分成各個過程函式,函式的輸入是各種型別的引數,執行後輸出結果。有了函式之後,提高了很多程式設計效率,但不幸的是,一個程式如果要引入所有的相關程式碼,本身也會變得臃腫不堪,於是就有了動態庫的概念。

        動態庫暴露給外部的都是函式名,甚至沒有引數。動態庫被載入入記憶體後,函式呼叫時,會根據函式名轉換成記憶體地址,這個地址是動態計算出來的。在執行過程中,都是call函式地址,不是函式名。動態庫如此好用,於是在windows系統中,出現了動態庫地獄,linux稍微好點,加入了版本號。windows的程式設計師們也學乖了,也加入了版本號,msvcrt後面都帶上了8、9等數字,表示版本。

2、多執行緒

        單程序的一個主要是問題是,一個阻塞操作會導致程序閒置,無法繼續後續的處理。檔案讀寫稍微還好點,在網路程式設計流行之後,這個問題愈加嚴重,你永遠無法知道另外一臺機器究竟什麼時候會掛掉,什麼時候會處理完。於是多程序解決方案出現了,apache是其中的傑出代表。

        多程序解決方案切換代價太大,就再次引入多執行緒。引入多執行緒之後,之前被忽視的問題就暴露出來了。就以最著名的的c標準庫,就有很多是不可重入,以至於後面加入同樣功能的可重入函式。在之前遺留的c程式碼,常常使用全域性變數,畢竟沒有多執行緒的顧慮,還要處處維護拷貝,是件痛苦的事情,而全域性變數就簡單多了。多執行緒還帶來同步問題,互斥鎖,讀寫鎖,條件變數。都是伴隨著多執行緒而出現的。

3、面向物件

        c++在繼承c的基礎上,引入了面向物件思想。強調物件內部的資料和函式是強內聚的,而物件和物件之間是鬆耦合的。同名函式可以有不同的輸入引數,是為多型。面向物件,更多體現出來的是一種理念上的先進。

 

二、服務架構的發展歷史

1、單機服務

        在網路出現之前,單機上其實也有服務程序,這些服務多數以程序間通訊方式交換資料,比如管道。早期的資料庫如Foxpro,就是一個簡單的檔案模式,因為格式足夠簡單,加上一個讀寫驅動就夠了。

2、網路服務

        得益於網路的發展,特別是網頁和瀏覽器的發展,服務需要處理的規模遠超出單機模式,服務模式以及對應的基礎元件和架構呈現井噴式發展。受制於最初網際網路頻寬限制,區域網反而先行發展,管理資訊系統以及之後的ERP,已經從二層架構發展成為三層架構。

        Apache是網頁服務發展的一個里程碑,後續的jsp和php的出現,從靜態網頁時代進入更靈活的動態網頁時代。

3、資料庫

        拋開早期的層次型資料庫和近期的NoSQL資料庫,關係型資料庫是資料管理系統發展的經典之作,即使經過了幾十年,依然活力十足。他讓開發擺脫了資料管理的桎梏,而專注於業務的開發,從而推動了三層架構的普及。

        資料集中管理帶來便利的同時,也造成了資料訪問的瓶頸。在業務服務增多的時候,對資料庫的壓力也會同時呈線性增長態勢。

4、SOA

        SOA出現之初,主要為了解決異構系統之間的整合,所以中介軟體以及協議定義和轉換成為重中之重,當然還包括了網路安全。也正因為異構系統之間的複雜,SOA在解決這個問題的同時,引入了很多重量級解決方案,比如WSDL。中介軟體是個好東西,解決位置解耦問題,但和資料庫一樣,存在瓶頸問題。特別是ESB,加入更多的功能,顯得臃腫不堪。

5、微服務

        微服務繼承了SOA很多優秀的理念,同時也擯棄了很多歷史負擔。因為SOA已經解決異構系統問題,所以微服務就不用背這個鍋了。Martin Fowler描述了很多微服務的特性,但核心就一個字“微”,其他特性都為解決因為微字出現的問題。可以想象下,原本一個程序,現在被拆成10個程序,要解決多少問題麼?

 

三、理念對應表

1、元件化

<1>、彙編 -->【程式碼太多】-->函式-->【程式太大】-->動態庫-->【關聯太多】-->面向物件。

<2>、單機服務-->【功能太多】-->網路服務-->【資料和邏輯混合】-->資料庫-->【異構太多】-->SOA-->【單服務過於複雜】-->微服務。

從上述的走向圖來看,元件化的理念從未離開我們,將大工程拆成小專案,更符合人類的行為模式。

2、作用域

<1>、全域性變數-->【受多點影響】-->結構成員-->【公共可見】-->物件成員-->【命名衝突】-->名空間

<2>、資料庫-->【受多服務影響】-->事務隔離-->【全域性可見】-->分散資料管理

資料的作用域傾向於越小越好,這在程式設計理念上是合理的。但是資料庫以及之後分散式儲存,更多考慮的是資料可靠性和安全性。再到微服務的獨立資料庫的做法,又回到原點。資料和程式碼的關係輪迴是個非常有意思的話題。

3、同步

<1>、單程序-->【效能瓶頸】-->多執行緒-->【訪問衝突】-->鎖機制-->【粒度太大】-->原子操作

<2>、單體服務-->【效能瓶頸】-->多服務-->【一致性】-->分散式事務-->【粒度太大】-->獨立資料庫

 

四、總結

        Martin Fowler在微服務的特性描述中,還提到的弱化通道,應該是針對於ESB臃腫不堪的功能。而基礎設施自動化,更多是解決微化之後帶來的後果,不然微服務就沒有辦法實施了。容錯設計也沒有什麼特點,拆得越細出錯概率越大,微服務的錯誤概率和運維成本遠超過單程序。至於斷路器,只能說和殺程序的作用很相似。

        在看完上面理念對應表,可以看到基本原則一直存在於軟體設計領域,唯一不同的是,在SOA之後,微服務將這些概念改造得更符合當前技術發展的需要。