微服務(wù)框架
目前主流的應(yīng)用分為兩種:
單體式應(yīng)用和微服務(wù)應(yīng)用,下面將具體對它們盡心能夠描述。
開發(fā)單體式應(yīng)用
假設(shè)你正準(zhǔn)備開發(fā)一款與Uber和Hailo競爭的出租車調(diào)度軟件,經(jīng)過初步會議和需求分析,你可能會手動或者使用基于Rails、Spring Boot、Play或者Maven的生成器開始這個新項目,它的六邊形架構(gòu)是模塊化的 ,架構(gòu)圖如下:

應(yīng)用核心是業(yè)務(wù)邏輯,由定義服務(wù)、域?qū)ο蠛褪录哪K完成。圍繞著核心的是與外界打交道的適配器。適配器包括數(shù)據(jù)庫訪問組件、生產(chǎn)和處理消息的消息組件,以及提供API或者UI訪問支持的web模塊等。
盡管也是模塊化邏輯,但是最終它還是會打包并部署為單體式應(yīng)用。具體的格式依賴于應(yīng)用語言和框架。例如,許多Java應(yīng)用會被打包為WAR格式,部署在Tomcat或者Jetty上,而另外一些Java應(yīng)用會被打包成自包含的JAR格式,同樣,Rails和Node.js會被打包成層級目錄。
這種應(yīng)用開發(fā)風(fēng)格很常見,因為IDE和其它工具都擅長開發(fā)一個簡單應(yīng)用,這類應(yīng)用也很易于調(diào)試,只需要簡單運行此應(yīng)用,用Selenium鏈接UI就可以完成端到端測試。單體式應(yīng)用也易于部署,只需要把打包應(yīng)用拷貝到服務(wù)器端,通過在負載均衡器后端運行多個拷貝就可以輕松實現(xiàn)應(yīng)用擴展。在早期這類應(yīng)用運行的很好。
單體式應(yīng)用的不足
不幸的是,這種簡單方法卻有很大的局限性。一個簡單的應(yīng)用會隨著時間推移逐漸變大。在每次的sprint中,開發(fā)團隊都會面對新“故事”,然后開發(fā)許多新代碼。幾年后,這個小而簡單的應(yīng)用會變成了一個巨大的怪物。這兒有一個例子,我最近和一個開發(fā)者討論,他正在寫一個工具,用來分析他們一個擁有數(shù)百萬行代碼的應(yīng)用中JAR文件之間的依賴關(guān)系。我很確信這個代碼正是很多開發(fā)者經(jīng)過多年努力開發(fā)出來的一個怪物。
一旦你的應(yīng)用變成一個又大又復(fù)雜的怪物,那開發(fā)團隊肯定很痛苦。敏捷開發(fā)和部署舉步維艱,其中最主要問題就是這個應(yīng)用太復(fù)雜,以至于任何單個開發(fā)者都不可能搞懂它。因此,修正bug和正確的添加新功能變的非常困難,并且很耗時。另外,團隊士氣也會走下坡路。如果代碼難于理解,就不可能被正確的修改。最終會走向巨大的、不可理解的泥潭。
單體式應(yīng)用也會降低開發(fā)速度。應(yīng)用越大,啟動時間會越長。比如,最近的一個調(diào)查表明,有時候應(yīng)用的啟動時間居然超過了12分鐘。我還聽說某些應(yīng)用需要40分鐘啟動時間。如果開發(fā)者需要經(jīng)常重啟應(yīng)用,那么大部分時間就要在等待中渡過,生產(chǎn)效率受到極大影響。
另外,復(fù)雜而巨大的單體式應(yīng)用也不利于持續(xù)性開發(fā)。今天,SaaS應(yīng)用常態(tài)就是每天會改變很多次,而這對于單體式應(yīng)用模式非常困難。另外,這種變化帶來的影響并沒有很好的被理解,所以不得不做很多手工測試。那么接下來,持續(xù)部署也會很艱難。
單體式應(yīng)用在不同模塊發(fā)生資源沖突時,擴展將會非常困難。比如,一個模塊完成一個CPU敏感邏輯,應(yīng)該部署在AWS EC2 Compute Optimized instances,而另外一個內(nèi)存數(shù)據(jù)庫模塊更合適于EC2 Memory-optimized instances。然而,由于這些模塊部署在一起,因此不得不在硬件選擇上做一個妥協(xié)。
單體式應(yīng)用另外一個問題是可靠性。因為所有模塊都運行在一個進程中,任何一個模塊中的一個bug,比如內(nèi)存泄露,將會有可能弄垮整個進程。除此之外,因為所有應(yīng)用實例都是唯一的,這個bug將會影響到整個應(yīng)用的可靠性。
最后,單體式應(yīng)用使得采用新架構(gòu)和語言非常困難。比如,設(shè)想你有兩百萬行采用XYZ框架寫的代碼。如果想改成ABC框架,無論是時間還是成本都是非常昂貴的,即使ABC框架更好。因此,這是一個無法逾越的鴻溝。你不得不在最初選擇面前低頭。
總結(jié)一下:一開始你有一個很成功的關(guān)鍵業(yè)務(wù)應(yīng)用,后來就變成了一個巨大的,無法理解的怪物。因為采用過時的,效率低的技術(shù),使得雇傭有潛力的開發(fā)者很困難。應(yīng)用無法擴展,可靠性很低,最終,敏捷性開發(fā)和部署變的無法完成。
微處理架構(gòu)——處理復(fù)雜事物
許多公司,比如Amazon、eBay和NetFlix,通過采用微處理結(jié)構(gòu)模式解決了上述問題。其思路不是開發(fā)一個巨大的單體式的應(yīng)用,而是將應(yīng)用分解為小的、互相連接的微服務(wù)。
一個微服務(wù)一般完成某個特定的功能,比如下單管理、客戶管理等等。每一個微服務(wù)都是微型六角形應(yīng)用,都有自己的業(yè)務(wù)邏輯和適配器。一些微服務(wù)還會發(fā)布API給其它微服務(wù)和應(yīng)用客戶端使用。其它微服務(wù)完成一個Web UI,運行時,每一個實例可能是一個云VM或者是Docker容器。
每一個應(yīng)用功能區(qū)都使用微服務(wù)完成,另外,Web應(yīng)用會被拆分成一系列簡單的Web應(yīng)用(比如一個對乘客,一個對出租車駕駛員)。這樣的拆分對于不同用戶、設(shè)備和特殊應(yīng)用場景部署都更容易。
每一個后臺服務(wù)開放一個REST API,許多服務(wù)本身也采用了其它服務(wù)提供的API。比如,駕駛員管理使用了告知駕駛員一個潛在需求的通知服務(wù)。UI服務(wù)激活其它服務(wù)來更新Web頁面。所有服務(wù)都是采用異步的,基于消息的通訊。微服務(wù)內(nèi)部機制將會在后續(xù)系列中討論。
這種微服務(wù)架構(gòu)模式深刻影響了應(yīng)用和數(shù)據(jù)庫之間的關(guān)系,不像傳統(tǒng)多個服務(wù)共享一個數(shù)據(jù)庫,微服務(wù)架構(gòu)每個服務(wù)都有自己的數(shù)據(jù)庫。另外,這種思路也影響到了企業(yè)級數(shù)據(jù)模式。同時,這種模式意味著多份數(shù)據(jù),但是,如果你想獲得微服務(wù)帶來的好處,每個服務(wù)獨有一個數(shù)據(jù)庫是必須的,因為這種架構(gòu)需要這種松耦合。下面的圖演示示例應(yīng)用數(shù)據(jù)庫架構(gòu)。
表面上看來,微服務(wù)架構(gòu)模式有點像SOA,他們都由多個服務(wù)構(gòu)成。但是,可以從另外一個角度看此問題,微服務(wù)架構(gòu)模式是一個不包含Web服務(wù)(WS-)和ESB服務(wù)的SOA。微服務(wù)應(yīng)用樂于采用簡單輕量級協(xié)議,比如REST,而不是WS-,在微服務(wù)內(nèi)部避免使用ESB以及ESB類似功能。微服務(wù)架構(gòu)模式也拒絕使用canonical schema等SOA概念。
表面上看來,微服務(wù)架構(gòu)模式有點像SOA,他們都由多個服務(wù)構(gòu)成。但是,可以從另外一個角度看此問題,微服務(wù)架構(gòu)模式是一個不包含Web服務(wù)(WS-)和ESB服務(wù)的SOA。微服務(wù)應(yīng)用樂于采用簡單輕量級協(xié)議,比如REST,而不是WS-,在微服務(wù)內(nèi)部避免使用ESB以及ESB類似功能。微服務(wù)架構(gòu)模式也拒絕使用canonical schema等SOA概念。
esb 總線:企業(yè)服務(wù)總線。上面標(biāo)黑的這條線說的是 在微服務(wù)框架中,服務(wù)與服務(wù)之間不是通過總線,而是通過rest ful來通信。
微服務(wù)架構(gòu)的好處
微服務(wù)架構(gòu)模式有很多好處。首先,通過分解巨大單體式應(yīng)用為多個服務(wù)方法解決了復(fù)雜性問題。在功能不變的情況下,應(yīng)用被分解為多個可管理的分支或服務(wù)。每個服務(wù)都有一個用RPC-或者消息驅(qū)動API定義清楚的邊界。微服務(wù)架構(gòu)模式給采用單體式編碼方式很難實現(xiàn)的功能提供了模塊化的解決方案,由此,單個服務(wù)很容易開發(fā)、理解和維護。
第二,這種架構(gòu)使得每個服務(wù)都可以有專門開發(fā)團隊來開發(fā)。開發(fā)者可以自由選擇開發(fā)技術(shù),提供API服務(wù)。當(dāng)然,許多公司試圖避免混亂,只提供某些技術(shù)選擇。然后,這種自由意味著開發(fā)者不需要被迫使用某項目開始時采用的過時技術(shù),他們可以選擇現(xiàn)在的技術(shù)。甚至于,因為服務(wù)都是相對簡單,即使用現(xiàn)在技術(shù)重寫以前代碼也不是很困難的事情。
第三,微服務(wù)架構(gòu)模式是每個微服務(wù)獨立的部署。開發(fā)者不再需要協(xié)調(diào)其它服務(wù)部署對本服務(wù)的影響。這種改變可以加快部署速度。UI團隊可以采用AB測試,快速的部署變化。微服務(wù)架構(gòu)模式使得持續(xù)化部署成為可能。
最后,微服務(wù)架構(gòu)模式使得每個服務(wù)獨立擴展。你可以根據(jù)每個服務(wù)的規(guī)模來部署滿足需求的規(guī)模。甚至于,你可以使用更適合于服務(wù)資源需求的硬件。比如,你可以在EC2 Compute Optimized instances上部署CPU敏感的服務(wù),而在EC2 memory-optimized instances上部署內(nèi)存數(shù)據(jù)庫。
springboot 微服務(wù)框架
在微服務(wù)架構(gòu)設(shè)計中,需要抽象出一些核心問題來統(tǒng)一解決,這包括九條核心問題。第一點是服務(wù)的注冊中心。第二是統(tǒng)一的接入服務(wù)接口。第三是服務(wù)的容錯和負載均衡保證服務(wù)的高可用。第四是服務(wù)的限流和降級保證核心服務(wù)的穩(wěn)定性。第五是服務(wù)系統(tǒng)的安全及全鏈路日志跟蹤。第六是支持多種通訊方式。第七是監(jiān)控和日志管理,第八是下面詳細描述各個核心問題的內(nèi)容:
- 服務(wù)注冊中心,主要實現(xiàn)服務(wù)注冊與服務(wù)發(fā)現(xiàn)。微服務(wù)架構(gòu)由一組獨立的微服務(wù)組成,這些微服務(wù)之間存在一種發(fā)現(xiàn)機制,目前我們通過服務(wù)注冊與發(fā)現(xiàn)來讓微服務(wù)可以感知彼此,微服務(wù)框架在啟動的時候,將自己的信息注冊到注冊中心,同時從注冊中心訂閱自己需要引用的服務(wù)。
- 統(tǒng)一的接入服務(wù)接口。由于把UI和后端服務(wù)分離。API Gateway是一個網(wǎng)關(guān)服務(wù)器,也可以說是進入系統(tǒng)的唯一節(jié)點。這跟面向?qū)ο笤O(shè)計模式中的Facade模式很像。API Gateway封裝內(nèi)部系統(tǒng)的架構(gòu),并且提供API給各個客戶端。API Gateway還可能有其他功能,如授權(quán)、監(jiān)控、負載均衡、緩存、請求分片和管理、靜態(tài)響應(yīng)處理等。
- 服務(wù)的容錯和負載均衡保證服務(wù)的高可用。為了保證微服務(wù)的高可用,每個微服務(wù)一般會有多個實例服務(wù)提供服務(wù),此時需要客戶端在進行服務(wù)的負載均衡;目前微服務(wù)框架中,現(xiàn)支持常見的負載均衡策略,如隨機,輪訓(xùn),hash,權(quán)重,連接數(shù),缺省是根據(jù)連接數(shù),連接數(shù)越少,優(yōu)先級越高。
- 服務(wù)的容錯可以保證核心服務(wù)的連續(xù)性。在調(diào)用服務(wù)集群的時候,如果一個微服務(wù)調(diào)用異常,如超時,或者發(fā)生連接異常,網(wǎng)絡(luò)異常,則根據(jù)容錯策略進行服務(wù)容錯,如果連續(xù)失敗多次,則需要直接熔斷,不再發(fā)起調(diào)用,這樣可以防止一個服務(wù)異常拖垮所有依賴它的服務(wù)。
- 服務(wù)的限流和降級等措施可以保證核心服務(wù)的穩(wěn)定性。隨著訪問量的增加,微服務(wù)架構(gòu)設(shè)置了一個系統(tǒng)能夠處理的極限閥值,超過這個閥值的請求則直接拒絕。同時,為了保證某些核心服務(wù)可用,需要對某些非核心業(yè)務(wù)進行降級。這些操作可以自動降級也可以人工降級。
- 安全控制和權(quán)限驗證:保障系統(tǒng)的安全。微服務(wù)架構(gòu)推薦采用token機制保證微服務(wù)的安全。用戶在登錄的時候會頒發(fā)給用戶一個token,用戶每次訪問平臺的時候,需要傳遞此token,后臺校驗此token的合法性,如果合法則可以訪問,如果沒有token或者token不合法,則禁止訪問。
- 支持多種通訊方式。在微服務(wù)架構(gòu)下,一般采用輕量級的方式進行通訊,每個微服務(wù)都統(tǒng)一對外暴露RESTFul服務(wù),無論是前端調(diào)用后端服務(wù),還是后端服務(wù)間的調(diào)用,都統(tǒng)一走RESTFul,這樣統(tǒng)一了協(xié)議棧。
- 日志和監(jiān)控管理。在微服務(wù)框架中,所有的系統(tǒng)調(diào)用邊界、請求接入接出邊界,都存在統(tǒng)一的日志埋點,這些日志埋點和監(jiān)控系統(tǒng)對接,可以方便的查看系統(tǒng)的運行各項指標(biāo),同時也可以根據(jù)日志跟蹤到一個服務(wù)從前到后的整個調(diào)用鏈路。
- 統(tǒng)一配置管理。統(tǒng)一的配置服務(wù)器為各應(yīng)用的所有環(huán)境提供了一個中心化的外部配置。這樣可以簡化很多開發(fā)過程中的繁瑣工作。
10.CI/CD自動化。快速完成源碼構(gòu)建、鏡像打包、應(yīng)用部署,實現(xiàn)微服務(wù)的高效運營。
服務(wù)注冊中心 即 服務(wù)發(fā)現(xiàn)。可以使用的工具有etcd、Spring Cloud Consul等。
額外的補充
zookeeper 使用的是 fast paxos共識算法。
etcd 使用的是raft共識算法。