在過去幾年中,出現了微服務架構的理念,它提倡將應用程序設計爲可獨立部署到額服務套件。雖然對於這種架構風格沒有明確的定義,可是它在業務能力,自動部署,智能終端以及語言和數據的分散控制方面有共同的特徵。git
微服務是軟件架構中的一個新名詞。在過去幾年中,能夠看到不少項目都採用了這種風格的架構,以致於他已經成爲了構建企業應用程序的默認樣式。然而,並無太多的信息能夠描述微服務架構的風格以及如何實現這種風格。程序員
簡而言之,微服務架構是將單應用開發成爲一套分別運行在獨立的線程並經過輕量級的機制如HTTP進行訪問的方法。這些服務圍繞業務功能構建,而且能夠獨立的全自動部署。這些服務無需集中管理,能夠用不一樣的編程語言編寫,並使用不一樣的數據存儲技術。github
在開始介紹微服務風格以前,能夠先將其和單機應用作一個對比:單機應用是指將一個應用做爲一個單元進行開發。企業應用一般包含三個部分:客戶端UI(包含在用戶瀏覽器上的HTML頁面和JS腳本),一個數據庫(關係型數據庫)和服務端應用。服務端應用會處理HTTP請求,執行業務邏輯,從數據庫獲取和更新數據,並選擇和生成HTML頁面返回給瀏覽器。系統的任何變動都須要從新構建和部署新版本的服務端應用。面試
單機應用是構建系統的一種通用方法。處理請求的全部業務邏輯都運行在單線程中,你能夠根據開發語言將應用份極爲類,方法和命名域。你能夠在筆記本上運行和測試應用,並使用部署流水線來確保變動已經進行過測試並部署到生產環境。你能夠經過在負載均衡器後面運行許多實例來水平擴展單機應用。數據庫
單機應用在初期至關成功,但漸漸的人們會感到挫敗--尤爲當應用被部署到雲商以後。變動週期被綁定在一塊兒:應用的一個小變動須要整個應用從新構建和部署。隨着時間的推移,一般很難保持一個良好的模塊化結構,使得更難以將對模塊的變動維持在單個模塊內。擴展須要擴展整個應用程序,而不是應用中須要更多資源的部分。編程
這種挫敗感引向了微服務架構風格:將應用構架爲一組服務。每一個服務不只可以獨立的部署和擴展,還可以提供一個穩定的模塊邊界,而且每一個服務用不一樣的語言開發。他們還能交由不一樣的團隊開發。瀏覽器
咱們並無表示微服務風格是創新的發明,它能夠追溯回Unix的設計理念。可是咱們認爲有人還沒能認真的考慮微服務架構,若是使用這種架構,軟件開發將會更方便。緩存
微服務架構雖然沒有正式的定義,可是咱們能夠嘗試描述這種架構的共同特色。就如別的試圖描述共同特徵的定義同樣,不是全部的微服務架構都具備全部的共同特徵,即使咱們指望大多數的微服務架構可以擁有這種特徵。所以咱們不會規定必定要遵循的微服務定義。微信
從參與軟件行業以來,咱們就一直指望經過組裝組件的方式構建系統,就像現實世界那樣。在過去幾十年中,咱們已經看到了各類語言的共有庫的大量發展。架構
說到組件,咱們遇到了何爲組件的挑戰。咱們認爲,組件是可獨立替換和升級的軟件單元。
微服務架構也會使用共有庫,可是組件化軟件的主要方法是將其拆分爲服務。咱們將庫定義爲連接到程序並使用內函數調用的組件,而服務則是進程外的組件,他們經過Web服務或是遠程調用之類的機制進行調用(這與OO程序中的服務的概念是不一樣的)
將服務用做組件(而不是庫)的一個主要緣由是服務能夠獨立部署。若是單進程中有一個包含多個庫的應用程序,任何一個庫的變動都須要從新部署整個應用。可是若是應用被分解爲多個服務,那麼單個服務的變動只須要從新部署單個服務就能夠了。這也不是絕對的,某些變動須要同時變動服務接口,從而致使多個服務的調整。可是一個好的微服務架構須要最小化這種變動,經過內聚服務邊界和遵循規範的演化機制。
將服務用做組件的另外一個結果是更明確的組件接口。大多數的語言都沒有用於顯式定義接口的良好機制。一般就是文檔化接口,防止客戶端破壞了組件的封裝,從而致使組件之間的過緊的耦合。經過服務之間的遠程調用避免了這個問題。
使用服務化也是有缺點的。遠程調用比進程內方法調用代價更高,所以遠程API使用起來更加笨拙。若是須要變動組件之間的職責分配,這種跨進程的變動將會更加麻煩。
在第一次類比中,咱們將服務與運行進程進行比較,但那只是一個粗略的對比。一個服務每每包含多個進程,這些進程會並行的開發和部署,好比該服務會包含應用進程和數據庫進程。
當試圖將大應用拆分紅各個部分時,一般管理者會從技術層面出發,將其拆分爲UI團隊,服務端邏輯開發團隊和數據庫團隊。當團隊按照這些方式分開時,即便是簡單的更改也可能致使跨團隊項目須要時間和預算批准。
設計系統的任何組織都將產生一種設計,其結構體現了組織內的溝通結構。
-- Melvyn Conway, 1967
而微服務風格的拆分方法是不一樣的,它是圍繞着業務能力進行拆分的。劃分出的團隊每每是擴領域的成員所組成的,即一個服務的開發團隊包含了開發完整應用的全部能力。
跨職能團隊負責構建和運營每一個產品,每一個產品之間經過消息總線進行通訊。
大型單機應用程序也能夠圍繞業務功能進行模塊化,儘管這種狀況不是很常見。固然,咱們會敦促一個開發龐大的單機應用程序的團隊沿着業務線劃分本身。咱們在這裏看到的主要問題是,它們每每圍繞太多的背景進行組織。此外,咱們看到模塊化生產線須要大量的規則來維護。更明確的服務組件的分離使得更容易保持團隊邊界清晰。
咱們看到的大多數應用程序開發工做都使用項目模型:其目的是提供一個將被完成的軟件。完成後,軟件將移交給維護組織,構建它的項目團隊將被解散。
微服務支持者傾向於避免使用這種模式,而更傾向於認爲團隊應該在產品的整個生命週期內擁有產品。對此的一個共同認知來源於亞馬遜的「你構建,你維護」的裏面,開發團隊對生產中的軟件負所有責任。這使開發人員可以看到他們的軟件在生產中的行爲,並增長與用戶的聯繫,由於他們必須提供軟件的支持工做。
產品的內核與業務要求緊密的聯繫在一塊兒。再也不僅僅將軟件視爲一組要完成的功能,它還有一個持續的使命,即如何幫助其用戶加強業務能力。
並非說單機應用程序沒法使用這種思想,更是由於較小的服務粒度可使得開發人員和用戶之間更容易創建和維持聯繫。
在不一樣進程之間創建通訊結構時,咱們已經看到許多產品和方法都強調將智能放入溝通機制自己。一個很好的例子是企業服務總線(ESB),ESB產品一般包括用於消息路由,編排,轉換和應用業務規則的複雜工具。
微服務社區傾向於另外一種方案:智能終端和非智能管道。從微服務構建的應用程序旨在儘量低耦合和高內聚:擁有本身的領域邏輯,在經典的Unix意義上更像是管道中的過濾器,接收請求,在其之上執行領域邏輯,而後輸出響應。
使用最多的兩個協議是HTTP請求響應協議和消息隊列。HTTP協議是整個互聯網架構的基礎。經過HTTP協議,常用的資源能夠經過緩存來減小程序員的工做。第二種方法是輕量級的消息總線之上的消息隊列。選擇的基礎設施一般是非智能的(僅進行消息路由)。像RabbitMQ或ZeroMQ這樣的簡單實現僅僅提供可靠的異步結構。智能的部分交給服務終端來完成。
在單機應用中,組件在同一個進程中執行,彼此間的通訊是經過方法調用來實現。將單機應用變動爲微服務結構最大的挑戰之一就是決定組件之間的通訊方式。從內存方法調用到RPC的簡單轉換會致使複雜的通訊軟件沒法正常執行。相反,你須要用粗粒度的方法替換細粒度的通訊。
集中治理的後果之一是在單一技術平臺上實現標準化的趨勢。經驗代表,這種方法是有限的 - 並不是全部問題和解決方案都是一一對應的。咱們更喜歡使用正確的工具來完成工做,雖然單機應用程序能夠在必定程度上利用不一樣的語言,但這並不常見。
將單機應用拆分爲服務後,咱們能夠在構建每一個組件時擁有選擇權。您想使用Node.js構建一個簡單的報告頁面嗎?徹底能夠。C++來開發實時組件?沒有問題。您想要換數據庫,以更好地適應一個組件的讀取行爲?放手去嘗試吧。
固然了,有這種選擇權並不意味着你必須這麼作。可是用這種方式分割系統才使得咱們擁有了這種選擇權。
構建微服務的團隊也更喜歡採用不一樣的標準方法。相比於使用在文檔上某處記錄的一套規則,他們更傾向於構建有用的工具,使得開發者在面對問題時可使用這種工具來解決。這些工具每每會在多個團隊中普遍使用。如今git和github已成爲主流的版本控制系統,開源實踐在內部變得愈來愈廣泛。
Netflix是遵循這一理念的組織的一個很好的例子。以庫的形式共享有用的,尤爲是通過實戰考驗的代碼,能夠鼓勵其餘開發人員以相似的方式解決相似的問題,而且能夠選擇不一樣的方法。共享庫每每側重於解決數據存儲,進程間通訊的常見問題。
去中心化的數據管理表現爲幾種形式。在最抽象的層面上,它意味着概念模型在不一樣系統之間會有所不一樣。這是在大型企業中集成時的常見問題,客戶的銷售視圖將與運維視圖不一樣。銷售視圖中稱爲客戶的某些內容可能根本不會出如今支持視圖中。而兩者共有的內容可能具備不一樣的屬性或者(更糟糕)共同的可是語義不一樣的屬性。
此問題在應用程序之間很常見,但也可能在應用程序中發生,特別是當該應用程序分爲單獨的組件時。一個有用的思考方式是領域驅動設計。領域驅動設計將複雜域劃分爲多個有界上下文,並映射出它們之間的關係。這個過程對單體應用和微服務架構都頗有用,可是微服務自己的關聯和自身的服務邊界就幫助明確了這種關聯。
除了分散概念模型決策以外,微服務還分散了數據存儲決策。雖然單個應用程序更喜歡單個邏輯數據庫來存儲持久性數據,但企業一般更喜歡跨越一系列應用程序的單個數據庫。微服務更喜歡讓每一個服務管理本身的數據庫,能夠是同一數據庫技術的不一樣實例,也能夠是徹底不一樣的數據庫系統。
跨微服務分散數據責任對更新操做有影響。處理更新的經常使用方法是在更新多個資源時使用事務來保證一致性。這種方法一般用於單機結構中。
用這樣的事務有助於保持一致性,但會產生顯着的時間耦合,這在多個服務中是有問題的。衆所周知,分佈式事務很難實現,所以微服務架構強調服務之間的無事務協調。明確提出一致性可能只是最終的一致性,而問題則經過補償操做來處理。
選擇以這種方式管理不一致是許多開發團隊面臨的新挑戰,可是它每每符合大多數的業務要求。企業一般會接收必定程度的不一致,以便快速響應需求,同時採起某種反向流程來應對錯誤。要修復錯誤的成本低於在更大的一致性下丟失業務的成本,那麼權衡是值得的。
在過去幾年中,基礎設施自動化技術發生了巨大變化:雲的發展下降了構建,部署和運行微服務的操做複雜性。
許多使用微服務構建的產品或系統都是由具備豐富的持續交付經驗的團隊構建的。以這種方式構建軟件的團隊普遍使用基礎設施自動化技術。這在下面顯示的構建管道中說明:
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~