什么是單體應(yīng)用?
如圖所示,這個系統(tǒng)采用了三層架構(gòu),表現(xiàn)層,業(yè)務(wù)邏輯層,數(shù)據(jù)訪問層,雖然三層架構(gòu)解決了應(yīng)用程序中代碼間調(diào)用復(fù)雜,代碼職責(zé)不清的問題。但是他只是將應(yīng)用在邏輯上分成了三層,并不是物理上的分層,通過編譯,打包,部署后,最終還是在同一臺機器的同一個進程中運行, 這種功能集中,代碼中心化,一個發(fā)布包,部署后運行在同一個進程的應(yīng)用程序,我們通常稱之為單體架構(gòu)應(yīng)用。
單體應(yīng)用的優(yōu)點?
- 易于開發(fā)
- 易于測試
- 易于部署
單體應(yīng)用的弊端?
- 維護成本高 - 隨著業(yè)務(wù)的不斷擴大,需求的持續(xù)增加,越來越多人加入開發(fā)團隊,代碼庫也在急劇的膨脹,在這種情況下,單體架構(gòu)的可維護性,靈活性在降低,而維護成本,技術(shù)架構(gòu)演進的成本,以及系統(tǒng)擴展成本等都在增加。
- 可靠性差 - 由于所有模塊都運行在同一進程中,任何模塊中的一個 bug,比如內(nèi)存泄漏都可能弄垮整個進程。
- 技術(shù)選型成本高 - 單體應(yīng)用會讓采用新框架和語言極其困難。舉例來說,你有兩百萬行使用 XYZ 框架的代碼,如果要使用 ABC 框架重寫代碼,無論時間還是成本都將非常高昂,即便新框架更好,這也就成為使用新技術(shù)的阻礙。
- 交付周期長 - 一般采用release train的方式,需要所用的功能都準(zhǔn)備好了才能發(fā)布。
微服務(wù)的定義
越來越多的公司,諸如亞馬遜、eBay、Netflix 等已經(jīng)通過采用微服務(wù)架構(gòu)解決了上面提到的問題,當(dāng)我們在聊微服務(wù)的時候,它代表著什么?
微服務(wù)架構(gòu)是一種架構(gòu)模式,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù),服務(wù)之間互相協(xié)調(diào)、互相配合,為用戶提供最終價值。每個服務(wù)運行在其獨立的進程中,服務(wù)與服務(wù)間采用輕量級的通信機制互相溝通(通常是基于HTTP協(xié)議的RESTful API)。每個服務(wù)都圍繞著具體業(yè)務(wù)進行構(gòu)建,并且能夠被獨立的部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等。另外,應(yīng)當(dāng)盡量避免統(tǒng)一的、集中式的服務(wù)管理機制,對具體的一個服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文,選擇合適的語言、工具對其進行構(gòu)建。
微服務(wù)與SOA
SOA
- SOA最早的出現(xiàn)是為了解決企業(yè)不同系統(tǒng)之間整合的問題,提出服務(wù)重用和消息總線。
- SOA中存在大量的編排,通常通過消息總線來承載業(yè)務(wù)邏輯,并構(gòu)建出重量級中心化的中間件。
- SOA有個很大的問題在于總線,按照這個思想,這些系統(tǒng)總會在某個環(huán)節(jié)上走向集中,所以去中心化做的很不徹底。
微服務(wù)
- 目標(biāo): 幫助企業(yè)更快的響應(yīng)變化
- 宗旨: 去中心化
微服務(wù)劃分
如何設(shè)計一個好的服務(wù)是微服務(wù)的核心,而領(lǐng)域驅(qū)動設(shè)計是其中關(guān)鍵的方法之一,請參考我之前的文章: https://qinnnyul.github.io/2018/08/13/ddd-concept/#more
微服務(wù)的設(shè)計原則
高內(nèi)聚低耦合
- 緊密關(guān)聯(lián)的事物應(yīng)該放在一起,每個服務(wù)是針對一個單一職責(zé)的業(yè)務(wù)能力的封裝,專注做好一件事情(每次只有一個更改它的理由)。如下圖:有四個服務(wù)a,b,c,d,但是每個服務(wù)職責(zé)不單一,a可能在做b的事情,b又在做c的事情,c又同時在做a的事情,通過重新調(diào)整,將相關(guān)的事物放在一起后,可以減少不必要的服務(wù)。
- 輕量級的通信方式
- 同步RESTful(GET/PUT/POST...),基于http,能讓服務(wù)間的通信變得標(biāo)準(zhǔn)化并且無狀態(tài),關(guān)于RESTful API的成熟度,可參
Richardson為REST定義的成熟度模型
- 異步(消息隊列/發(fā)布訂閱)
- 同步RESTful(GET/PUT/POST...),基于http,能讓服務(wù)間的通信變得標(biāo)準(zhǔn)化并且無狀態(tài),關(guān)于RESTful API的成熟度,可參
-
避免在服務(wù)與服務(wù)之間共享數(shù)據(jù)庫
高內(nèi)聚.png
高度自治
- 獨立部署運行和擴展
- 每個服務(wù)能夠獨立被部署并運行在一個進程內(nèi)
- 這種運行和部署方式能夠賦予系統(tǒng)靈活的代碼組織方式和發(fā)布節(jié)奏,使得快速交付和應(yīng)對變化成為可能。
- 獨立開發(fā)和演進
- 技術(shù)選型靈活,不受遺留系統(tǒng)技術(shù)棧的約束。
- 合適的業(yè)務(wù)問題可以選擇合適的技術(shù)棧,可以獨立的演進
- 服務(wù)與服務(wù)之間采取與語言無關(guān)的API進行集成
- 獨立的團隊和自治
- 團隊對服務(wù)的整個生命周期負責(zé),工作在獨立的上下文中, 誰開發(fā),誰維護。
以業(yè)務(wù)為中心
- 每個服務(wù)代表了特定的業(yè)務(wù)邏輯
- 有明顯的邊界上下文
- 圍繞業(yè)務(wù)組織團隊
- 能快速的響應(yīng)業(yè)務(wù)的變化
- 隔離實現(xiàn)細節(jié),讓業(yè)務(wù)領(lǐng)域可以被重用
彈性設(shè)計
- 設(shè)計可容錯的系統(tǒng)
- 擁抱失敗,為已知的錯誤而設(shè)計
- 依賴的服務(wù)掛掉
- 網(wǎng)絡(luò)連接問題
- 設(shè)計具有自我保護能力的系統(tǒng)
- 服務(wù)隔離
- 服務(wù)降級
- 限制使用資源
- 防止級聯(lián)錯誤
Netfilix 提供了一個比較好的解決方案,具體的應(yīng)對措施包括:網(wǎng)絡(luò)超時/限制請求的次數(shù)/斷路器模式/提供回滾等。
Hystrix記錄那些超過預(yù)設(shè)定的極限值的調(diào)用。它實現(xiàn)了circuit break模式,從而避免了無休止的等待無響應(yīng)的服務(wù)。如果一個服務(wù)的錯誤率超過預(yù)設(shè)值,Hystrix將中斷服務(wù),并且在一段時間內(nèi)所有對該服務(wù)的請求會立刻失效。Hystrix可以為請求失敗定義一個fallback操作,例如讀取緩存或者返回默認值。
日志與監(jiān)控
當(dāng)產(chǎn)品環(huán)境出錯時,需要快速的定位問題,檢測可能發(fā)生的意外和故障。而日志與監(jiān)控是快速定位和預(yù)防的不二選擇,在微服務(wù)架構(gòu)中更是至關(guān)重要。
- 高度可觀察,我們需要對正在發(fā)生的事情有一個整體的視角。
- 聚合你的日志,聚合你的數(shù)據(jù),從而當(dāng)你遇到問題時,可以深入分析原因。
- 當(dāng)需要重現(xiàn)令人討厭的問題,或僅僅查看你的系統(tǒng)在生產(chǎn)環(huán)境如何交互時,
關(guān)聯(lián)標(biāo)識
可以幫助你跟蹤系統(tǒng)間的調(diào)用。
監(jiān)控主要包括服務(wù)可用狀態(tài)、請求流量、調(diào)用鏈、錯誤計數(shù),結(jié)構(gòu)化的日志、服務(wù)依賴關(guān)系可視化等內(nèi)容,以便發(fā)現(xiàn)問題及時修復(fù),實時調(diào)整系統(tǒng)負載,必要時進行服務(wù)降級,過載保護等等,從而讓系統(tǒng)和環(huán)境提供高效高質(zhì)量的服務(wù)。
比如商業(yè)解決方案splunk,sumologic
,以及開源產(chǎn)品ELK他們都可以用于日志的收集,聚合,展現(xiàn),并提供搜索功能,基于一定條件,觸發(fā)郵件警告。
Spring boot admin
也可以用于服務(wù)可用性的監(jiān)控, hystrix
除了提供熔斷器機制外,它還收集了一些請求的基本信息(比如請求響應(yīng)時間,訪問計算,錯誤統(tǒng)計等),并提供現(xiàn)成的dashboard將信息可視化。
關(guān)于性能監(jiān)控和調(diào)用鏈追蹤,考慮使用dynatrace和zipkin/Sleuth
自動化
在微服務(wù)架構(gòu)下,面臨如下挑戰(zhàn):
- 分布式系統(tǒng)
- 多服務(wù),多實例
- 手動測試,部署,發(fā)布太消耗時間
- 反饋周期太長
傳統(tǒng)的手工運維方式必然要被淘汰,微服務(wù)的實施是有一定的先決條件:那就是自動化,當(dāng)服務(wù)規(guī)模化后需要更多自動化
和標(biāo)準(zhǔn)化
的手段來提升效能和降低成本。
- 自動化測試必不可少,因為對比單塊系統(tǒng),確保我們大量的服務(wù)正常工作是一個更復(fù)雜的過程。
- 調(diào)用一個統(tǒng)一的命令行,以相同的方式把系統(tǒng)部署到各個環(huán)境。
- 考慮使用環(huán)境定義來幫助你明確不同環(huán)境間的差異,但同時保持使用統(tǒng)一的方式進行部署的能力。
- 考慮創(chuàng)建自定義鏡像來加快部署,并且擁抱全自動化創(chuàng)建不可變服務(wù)器的實踐。
自動化一切可以自動化的
,降低部署和發(fā)布的難度, 比如: 在持續(xù)集成和持續(xù)交付中,自動化編譯,測試,安全掃描,打包,集成測試,部署,隨著服務(wù)越來越多,在發(fā)布過程中,需要進一步自動化藍綠部署(做到老版本到新版本的平滑過渡)還可以使用pipeline as code的實踐,用代碼來描述你的流水線。關(guān)于部署有很多選擇,可以使用虛擬機,容器docker,或者流行的無服務(wù)架構(gòu)lambda(AWS Lambda 也有一些明顯的局限。它并不適合被用來部署長期運行的服務(wù),請求需要在 300 秒內(nèi)完成,當(dāng)然你可以通過hack的方式延遲時間)。
然后, 可以采用基礎(chǔ)設(shè)施及代碼的實踐,比如亞馬遜的cloudformation
,還有terrform
,通過代碼來描述計算和網(wǎng)絡(luò)等基礎(chǔ)設(shè)施, 可以快速為一個全新的服務(wù),構(gòu)架它所需要的環(huán)境,保持各環(huán)境的一致性
。
康威定律
一個系統(tǒng)的架構(gòu),反應(yīng)了組織的溝通結(jié)構(gòu)
這就要求我們應(yīng)該將服務(wù)的所用權(quán)和團隊對齊,當(dāng)兩者不一致的時候,我們會發(fā)現(xiàn)很多的摩擦點。
最后小結(jié): 微服務(wù)的目標(biāo)述求是為了提供響應(yīng)力,它圍繞業(yè)務(wù)能力進行構(gòu)建,讓一切去中心化是微服務(wù)的最高宗旨,在設(shè)計微服務(wù)的時候,是需要具備一定前提條件的(你必須是那個高個子
),請參考上面的設(shè)計原則。很早以前寫的關(guān)于微服務(wù)的咨詢,可以去這里下載一些PPT: https://wenku.baidu.com/view/fd9dea34dcccda38376baf1ffc4ffe473268fd42