- Java內存管理面試指南一
- Java基礎面試指南一
- Java基礎面試指南二
- Java基礎面試指南三
- Java基礎面試指南四
- Java線程面試指南一
- Java線程面試指南二
- Redis面試指南一
- Kafka面試指南一
- Spring面試指南一
- SpringBoot面試指南一
- 微服務面試指南一
1. 什么是微服務,為什么有人要考慮實現它.
微服務是一種架構樣式,其結構和應用程序是圍繞業務功能組織的松散耦合,可獨立維護,可測試和可部署的服務的集合.
如果您以業務為中心,並且想要在沒有技術限制的情況下有效地解決用例或問題,想要無限擴展獨立的服務,易於維護和管理以及可獨立測試的高可用性無狀態服務,那么我們將繼續實施微服務架構.
2. 什么時候應該考慮微服務類型的架構?
**有兩種情況. **
- 如果您已經擁有一個整體應用程序,並且該應用程序的增長到一定程度,在擴展方面存在問題,或者我們無法跨不同項目/平台重新利用組件/模塊/服務,則需要這樣做. 同時實現新功能是痛苦的,而且更容易出錯,並且很難進一步擴展.
- 對於尚未開始實施的新應用程序,我們可以考慮一個有效實施的業務案例,該業務案例將來可以輕松維護,測試和擴展,並且可以同時用於其他項目/產品/平台. .
3. 您將如何測試基於微服務的架構?
應該進行單元測試和集成測試,以測試微服務的所有功能. 還應該進行基於組件的測試.
人們應該通過合同測試來斷言客戶的期望沒有打破. 但是,微服務的端到端測試應該僅測試關鍵流程,因為這些流程很耗時. 測試可以從兩個方面進行,消費者驅動的合同測試和消費者方的合同測試.
您還可以利用命令查詢職責隔離來查詢多個數據庫並獲得持久數據的組合視圖.
4. 什么是服務發現?它有什么幫助?
在將docker映像動態部署在任何計算機或IP +端口組合上的雲環境中,相關服務在運行時很難更新. 僅出於此目的而創建服務發現.
服務發現是在微服務架構下運行的服務之一,它注冊在服務網格下運行的所有服務的條目. 所有操作都可以通過REST API獲得. 因此,每當服務啟動並運行時,各個服務便會向服務發現服務進行注冊,並且服務發現服務會保持心跳,以確保這些服務處於活動狀態. 這也用於監視服務的目的. 服務發現還有助於在以公平方式部署的服務之間分配請求.
5,什么是客戶端和服務器端服務發現?
在這種體系結構模式中,客戶端不是連接到負載平衡器,而是直接連接到服務注冊表並嘗試從中獲取數據或服務.
一旦獲得所有數據,它就會自行進行負載平衡,並直接與需要與之通信的服務聯系.
在存在多個代理層並且由於多層通信而發生延遲的情況下,這可能會有好處.
在服務器端發現中,代理層或API網關稍后會嘗試連接到服務注冊表,然后再調用適當的服務. 客戶端在此處連接到該代理層或API網關層.
6. 說明如何擴展基於微服務的系統?
假設大多數提供商都使用微服務架構,
- 可以通過啟動更多容器來增加服務實例的數量來擴展系統.
- 也可以將其應用於微服務層的緩存,因為微服務將是事實的唯一來源,因此緩存的失效可以非常容易地實現,因此可以輕松管理.
- 也可以在API網關層引入緩存,在其中可以定義緩存規則,例如何時使緩存無效.
- 當需求較少時,也可以關閉一些容器. 也就是說,按比例縮小.
7. 定義微服務架構?
微服務架構是一種開發由許多小型自治服務組成的可伸縮,分布式和高度自動化系統的樣式. 它不是一項技術,而是SOA衍生出的一種新趨勢.
沒有單一定義可以完全描述術語“微服務”. 一些著名的作者試圖通過以下方式對其進行定義:
- 微服務是可以協同工作的小型自治服務.
- 帶有邊界上下文的松散耦合的面向服務的體系結構.
- 微服務架構是在架構級別應用單責任原則的自然結果.

8. 微服務和SOA之間的區別
_微服務是SOA的延續. _
SOA由於其分布式體系結構方法而開始獲得發展,並在2006年左右出現,以解決大型單片應用程序的問題.
這些架構(SOA和微服務)都具有一個共同點,即它們都是分布式架構,並且都具有很高的可伸縮性. 在這兩種服務中,服務組件都是通過遠程訪問協議(RMI,REST,SOAP,AMQP,JMS等)進行遠程訪問的. 兩者都是模塊化的,通過設計可以松散地耦合在一起,並具有很高的可擴展性. 在輕量級容器,Docker,編排框架(Kubernetes,Mesos)出現之后,微服務在2000年底開始引起關注. 微服務在概念上與SOA有很大的不同-
- SOA使用企業服務總線進行通信,而微服務使用REST或其他不太復雜的消息傳遞系統(AMQP等). 同樣,微服務遵循“智能端點和啞點”,這意味着當微服務需要另一個作為依賴時,它應直接使用它,而無需任何路由邏輯/組件來處理管道.
- 在微服務中,服務部署和管理應該是完全自動化的,而SOA服務通常是在部署整體中實現的.
- 通常,微服務比SOA趨向要小得多. 這里我們不在這里討論代碼庫,因為很少有語言比其他語言更冗長. 我們正在談論服務本身的范圍(問題域). 微服務通常以更好的方式做一件事.
- 微服務應擁有自己的數據,而SOA可以共享一個公共數據庫. 因此,一個微服務不應允許另一個微服務直接更改/讀取其數據.
- 經典SOA更加受平台驅動,而在微服務方面,我們具有很多技術獨立性. 每個微服務都可以根據其自身的功能要求擁有自己的技術堆棧. 因此,微服務在各個維度上提供了更多選擇.
- 微服務對外部環境的假設盡可能少. 微服務應管理自己的功能域和數據模型.
9. 什么是有界上下文?
有界上下文是域驅動設計中的中心模式. 在有界上下文中,與域相關的所有內容在內部上下文中都是可見的,但對其他有界上下文是不透明的. DDD通過將大型模型划分為不同的有界上下文並明確說明它們之間的相互關系來處理它們.
_整體概念模型問題 _
整個組織的單一概念模型很難處理. 這種統一模型的唯一好處是,在整個企業范圍內集成都很容易,但是缺點很多,例如:
- 首先,很難建立一個適用於整個組織的模型.
- 其他人(團隊)很難理解它.
- 更改這種共享模型以適應新的業務需求非常困難. 這種變化的影響將在團隊之間廣泛傳播.
- 任何大型企業都需要一個非常大或抽象的模型.
- 單個詞的含義在組織的不同部門中可能有所不同,因此可能很難提出一個統一的模型. 即使創建了這樣的模型,也會在團隊中引起很多混亂.
10. 微服務架構的特征
- 高凝聚力 -小,專注於做好一件事. 小並不意味着更少的代碼行,因為很少有編程語言比其他語言更冗長,但這意味着單個微服務所能滿足的最小功能范圍.
- 松散耦合 -自主-能夠獨立部署不同服務的能力以及可靠性,這是因為即使另一個服務出現故障,該服務也可以運行.
- 限界上下文 -一個微服務供應域中的界上下文. 通過使用該有界上下文的接口,它與域的其余部分進行通信.
- 圍繞業務能力而非技術進行組織.
- 持續交付和基礎設施自動化.
- 向后兼容的版本控制. 生產環境中甚至可以存在相同微服務的多個版本.
- 容錯 -如果一項服務失敗,它將不會影響系統的其余部分. 例如,如果為電子商務提供評論和評論的微服務失敗,則網站的其余部分應運行良好.
- 分散式數據管理,每個服務擁有其數據庫,而不是單個共享數據庫. 每個微服務都可以自由選擇適合其業務用例的數據庫類型(例如,RDBMS用於訂單管理,NoSql用於電子商務網站的目錄管理)
- 最終一致性 -事件驅動的異步更新.
- 安全性 -每個微服務都應具有保護其自身資源免受未經授權訪問的能力. 這是通過使用無狀態安全性機制(例如帶有OAuth2的JSON Web令牌(JWT,發音為jot))實現的.
11. 使用微服務架構有什么好處?
與在應用程序中使用整體式體系結構相比,采用微服務體系結構可帶來許多好處,包括:
- 自主部署
在單個微服務上工作的分散團隊大多彼此獨立,因此更改服務不需要與其他團隊協調. 這可以導致明顯更快的釋放周期. 在現實的單片應用程序中,很難實現相同的目標,因為微小的變化可能需要整個系統的回歸.
- 理念轉變
系統架構的微服務風格強調自由文化,單一責任,團隊自治,更快的發布迭代和技術多樣化.
- 技術多元化
與單片應用程序不同,微服務沒有綁定到一個技術堆棧(Java,.Net,Go,Erlang,Python等). 每個團隊都可以自由選擇最適合其要求的技術堆棧. 例如,我們可以自由地為微服務選擇Java,為其他服務選擇c ++,為另一個服務選擇Go.
- DevOps文化
該術語來自“開發”和“運營”的縮寫. 這種文化強調產品管理,軟件開發和運營團隊之間的有效溝通與協作. 如果正確實施DevOps文化,可以縮短開發周期,從而加快產品上市時間.
12 什么是多語種持久性?這個想法也可以在整體應用中使用嗎?
多語言持久性是關於在單個分布式系統中使用不同的數據庫來滿足不同的業務需求. 我們在市場上已經有不同的數據庫產品,每種產品都可以滿足特定的業務需求,例如:
- 關系數據庫管理系統
關系數據庫用於滿足交易需求(存儲財務數據,報告要求等)
- MongoDB
面向文檔的數據庫用於滿足面向文檔的需求(例如,產品目錄). 文檔是無架構的,因此架構中的更改可以輕松容納到應用程序中.
- Cassandra / Amazon DynamoDB
基於鍵值對的數據庫(用戶活動跟蹤,分析等). DynamoDB可以存儲文檔以及鍵值對.
- Redis
在內存分布式數據庫(用戶會話跟蹤)中,其主要用作多個微服務之間的分布式緩存.
- Neo4j
圖表數據庫(社交關系,建議等)
_Polyglot Persistence的 _好處是多方面的,可以在整體以及微服務架構中獲得. 任何體面大小的產品都會有各種各樣的需求,僅憑一種數據庫就無法滿足. 例如,如果對特定的微服務沒有事務需求,那么使用鍵值對或面向文檔的NoSql比使用事務性RDBMS數據庫更好.
參考:https : //martinfowler.com/bliki/PolyglotPersistence.html
13 什么是應用程序的十二要素?
十二要素應用程序是一種用於編寫作為服務運行的Web應用程序的最新方法(和/或宣言).

- 程式庫
一個代碼庫,多個部署. 這意味着我們僅應為不同版本的微服務使用一個代碼庫. 分支可以,但不同的存儲庫則不行.
- 依存關系
明確聲明並隔離依賴項. 聲明建議不要依賴主機上的軟件或庫. 每個依賴項都應放入pom.xml或build.gradle文件中.
- Config
將配置存儲在環境中. 不要在源代碼存儲庫中提交特定於環境的配置(最重要的是:密碼). Spring Cloud Config為分布式系統中的外部化配置提供服務器和客戶端支持. 使用Spring Cloud Config Server,您可以集中管理所有環境中應用程序的外部屬性.
- 支持服務
將支持服務視為附加資源. 無論您是管理外部服務還是其他團隊,微服務都應平等對待外部服務. 例如,即使從屬微服務是由您自己的團隊開發的,也不要在您的應用程序代碼中硬編碼從屬服務的絕對URL. 例如,不要在RestTemplate中對其他服務的URL進行硬編碼,而使用Ribbon(帶有或不帶有Eureka)來定義URL:
- Release & Run
嚴格分開構建和運行階段. 換句話說,您應該能夠構建或編譯代碼,然后將其與特定的配置信息結合起來以創建特定的發行版,然后有意地運行該發行版. 在運行時更改代碼應該是不可能的,例如,直接在tomcat中更改類文件. 每個版本的發行版都應該始終有一個唯一的ID,主要是時間戳記. 發布信息應該是不變的,任何更改都應導致新的發布.
- Processes
將應用程序作為一個或多個無狀態進程執行. 這意味着我們的微服務本質上應該是無狀態的,並且不應依賴於內存或文件系統中存在的任何狀態. 實際上,狀態不屬於代碼. 因此,沒有粘性會話,沒有內存中的緩存,沒有本地文件系統的存儲等. 應該使用分布式緩存(如memcache,ehcache或Redis)代替
- 端口綁定
通過端口綁定導出服務. 這是關於使您的應用程序獨立運行,而不是依賴您要在其中部署的應用程序服務器的運行實例. Spring Boot提供了一種機制,可以創建一個包含所有依賴項和嵌入式servlet容器(jetty或tomcat)的可自我執行的uber jar.
- 並發
通過過程模型進行橫向擴展. 在十二要素應用程序中,流程是一等公民. 這並不排除各個進程通過運行時VM內的線程或在諸如EventMachine,Twisted或Node.js之類的工具中找到的異步/事件模型來處理其自身的內部多路復用. 但是單個VM只能增長得如此之大(垂直規模),因此應用程序還必須能夠跨越多個物理機上運行的多個進程. 十二因子應用程序進程絕不應寫入PID文件,而應依賴於操作系統進程管理器,例如systemd-雲平台上的分布式進程管理器.
- Disposability
十二要素應用程序的過程是一次性的,這意味着它們可以立即啟動或停止. 這有利於快速彈性擴展,代碼或配置更改的快速部署以及生產部署的穩定性. 流程應努力減少啟動時間. 理想情況下,從啟動命令執行到啟動並准備好接收請求或作業的過程需要花費幾秒鍾的時間. 較短的啟動時間為發布過程和擴展提供了更大的靈活性;並且它有助於增強魯棒性,因為在需要時,流程管理器可以更輕松地將流程移至新的物理機.
- 開發/線上一致
保持開發,暫存和生產盡可能相似. 您的開發環境應該幾乎與生產環境相同(例如,避免某些“在我的機器上工作”的問題). 但是,這並不意味着您的操作系統必須是在生產環境中運行的操作系統. Docker可用於為您的微服務創建邏輯隔離.
- 日志
將日志視為事件流,僅將所有日志發送到stdout. 但是,大多數Java開發人員不同意這個建議.
- 管理流程
一次性運行管理/管理任務. 例如,應該完全使用單獨的過程來運行數據庫遷移.
14. 微服務面臨哪些挑戰?
- 由於生產系統中大量流程的激增,DevOps是必須的. 如何啟動和停止服務團隊?
- 分布式計算的復雜性,例如“網絡延遲,容錯,消息序列化,不可靠的網絡,異步o / p處理,應用程序層中不同的負載,分布式事務等”.
- 如何以最小的努力在大型服務群中進行配置更改?
- 如何部署單個微服務的多個版本並適當地路由調用?
- 當微服務開始意外崩潰時,如何斷開其與生態系統的連接?
- 如何隔離發生故障的微服務並避免整個生態系統中的級聯故障?
- 考慮到服務在任何時間點都可能上升或下降,如何以彈性方式發現服務?
- 如何匯總服務中的日志/指標?如何識別跨微服務范圍的單個客戶端請求的不同步驟?
15為什么微服務比單體應用更好?
微服務體系結構旨在開發可安全擴展的大型分布式系統. 微服務架構相對於整體而言有很多好處,例如:
- 單體應用是作為一個整體構建的,它通常由3個組件組成–數據庫(通常是RDBMS),服務器端可執行文件(部署在tomcat,websphere等中的war文件)和客戶端接口(JSP等).
- 每當我們要添加/更新功能時,開發人員都需要更改這三個組件中的至少一個並將新版本部署到生產中. 整個系統緊密耦合,在選擇技術堆棧方面有局限性,凝聚力低.
- 當我們需要縮放整體時,可以通過一次又一次地復制大war / ear文件,在多台機器上部署相同版本的整體. 一切都包含在一個可執行文件中.
- 另一方面,微服務架構由小型的自治服務組成,這些服務由業務功能划分,業務功能主要通過異步方式在網絡上相互通信.

如上面的示例所示,典型的整體eShop應用程序通常是部署在單個JVM進程(tomcat / jboss / websphere等)中的大型war文件. 整體中的不同組件使用進程內通信(例如直接方法調用)相互通信. 一個或多個數據庫在整體應用程序的不同組件之間共享.
16. 如何將大型應用程序轉換為微服務架構?
微服務應該是自主的,並應根據業務功能進行划分. 每個軟件組件都應具有單一的明確定義的職責(又稱“單一職責原則”),並且應使用“受限上下文”的原則(由“域驅動設計”定義)來創建具有高度凝聚力的軟件組件.
例如,一個電子商務站點可以根據其業務功能分為以下微服務:
- 產品目錄
負責產品信息,搜索產品,過濾產品和產品方面.
- 庫存
負責管理產品庫存(庫存/數量和方面).
- 產品評論和反饋
收集用戶對產品的反饋.
- 訂單
負責創建和管理訂單.
- 付款方式
在線和離線處理付款(貨到付款).
- 出貨量
根據訂單管理和跟蹤貨運.
- 用戶帳號
管理用戶及其偏好.
- 推薦建議
根據用戶的偏好或過去的購買來推薦新產品.
- 通知事項
有關訂單,付款和裝運的電子郵件和SMS通知.
客戶端應用程序(瀏覽器,移動應用程序)將通過API網關與這些服務進行交互,並將相關信息呈現給用戶.
17. 如果啟動期間無法連接到Config服務器,如何在啟動時停止基於Spring Boot的微服務?
如果要在引導過程中無法找到配置服務器時停止該服務,則需要在微服務的bootstrap.yml中配置以下屬性:
spring:
cloud:
config:
fail-fast: true
當引導過程中無法訪問config-server時,使用此配置將使微服務啟動失敗並發生異常.
我們可以啟用重試機制,其中微服務將在拋出異常之前重試6次. 我們只需要在類路徑中添加spring-retry和spring-boot-starter-aop即可啟用此功能.
build.gradle:-
dependencies {
compile('org.springframework.boot:spring-boot-starter-aop')
compile('org.springframework.retry:spring-retry')
...
}
18 單個微服務應該有多大?
良好的經驗法則(盡管非特定性)應盡可能小,但應盡可能大,以代表他們擁有的領域概念(由馬丁·福勒(Martin Fowler)說)
規模不應成為微服務中的決定因素,而應使用有限上下文原則和單一責任原則將業務能力隔離到單個微服務邊界中.
微服務通常很小,但並非所有的小服務都是微服務. 如果任何服務未遵循“綁定上下文原則”,“單一職責原則”等,則它不是微服務,無論其大小如何. 因此,規模並不是服務成為微服務的唯一資格標准.
實際上,微服務的大小在很大程度上取決於您選擇的語言(Java,Scala,PHP),因為很少有語言比其他語言更冗長.
19 微服務如何相互通信?
微服務通常使用諸如HTTP上的REST之類的簡單協議進行集成. 其他通信協議也可以用於集成,例如AMQP,JMS,Kafka等.
通信協議可以大致分為兩類:同步通信和異步通信.
- 同步通訊
RestTemplate,WebClient,FeignClient可用於兩個微服務之間的同步通信. 理想情況下,我們應該最小化微服務之間的同步調用數量,因為網絡很脆弱並且會引入延遲. 功能區-客戶端負載平衡器可用於在RestTemplate頂部更好地利用資源. Hystrix斷路器可用於優雅地處理部分故障,而不會對整個生態系統造成連鎖影響. 應該不惜一切代價避免分布式提交,相反,我們將選擇使用異步通信實現最終的一致性.
- 異步通訊
在這種類型的通信中,客戶端不等待響應,而是僅將消息發送到消息代理. AMQP(如RabbitMQ)或Kafka可用於跨微服務的異步通信,以實現最終的一致性.
20 微服務中首選的通信方式是什么:同步還是異步?
- 您必須使用一些可靠的隊列機制(RabbitMQ,AMQP等)在處理HTTP POST / PUT(任何修改數據的)請求時使用異步通信.
- 可以在API網關級別將同步通信用於聚合模式. 但是,此聚合除聚合外不應包含任何業務邏輯. 不得在網關上轉換數據值,否則,它將無法達到“受限上下文”的目的. 在異步通信中,事件應發布到隊列中. 事件包含有關域的數據,它不應該告訴對此數據做什么(操作).
- 如果微服務到微服務的通信仍然需要GET操作進行同步通信,那么請認真考慮為有限的上下文重新划分微服務,並在積壓/技術債務中創建一些任務.
21 在微服務環境下,業務流程和編排有什么區別?
在業務流程中,我們依靠中央系統以某種方式控制和調用其他微服務來完成給定的任務. 中央系統維護整個工作流程的每個步驟和順序的狀態. 在編排中,每個微服務都像狀態機一樣工作,並根據其他部分的輸入做出反應. 每個服務都知道如何對來自其他系統的不同事件做出反應. 在這種情況下,沒有中央命令.
業務流程是緊密耦合的方法,並且是微服務體系結構中的反模式. 鑒於此,應盡可能采用編排的松散耦合方法.
例
假設我們要開發一種微服務,該服務將在虛擬的電子商店中發送產品推薦電子郵件. 為了發送建議,我們需要訪問位於不同微服務中的用戶的訂單歷史記錄.
在編排方法中,此新的建議微服務將同步調用訂購服務並獲取相關數據,然后根據其過去的購買量來計算建議. 為一百萬用戶執行此操作將變得很麻煩,並將兩個微服務緊密結合在一起.
在編排方法中,我們將使用基於事件的異步通信,每當用戶進行購買時,訂單服務都會發布事件. 推薦服務將監聽此事件並開始建立用戶推薦. 這是一種松散耦合的方法,具有高度的可擴展性. 在這種情況下,事件並不能說明操作,而只能說明數據.
22. 微服務發布到生產中的頻率如何?
這個問題沒有正確的答案,可能每十分鍾,每小時或每周發布一次. 這完全取決於您在軟件開發生命周期的不同級別上的自動化程度-構建自動化,測試自動化,部署自動化和監視. 當然還有業務需求-在一次發布中,您關心的低風險變化有多小.
在一個理想的世界中,每個微服務的邊界都明確定義(有界上下文),並且給定的服務不會影響其他微服務,您可以輕松地一天完成多次部署而不會造成很大的復雜性.
部署/發布頻率示例
- 據記錄,亞馬遜在2011年5月平均每11.6秒進行一次生產更改.
- Github以其積極的工程實踐而聞名,平均每天將代碼部署到生產中60次.
- Facebook每天發布兩次.
- 許多Google服務每周都會發布多個版本,而Google中的幾乎所有內容都是在主線上開發的.
- Etsy每天部署超過50次.
23 什么是雲原生應用程序?
雲原生應用程序(NCA)是一種應用程序開發樣式,鼓勵在連續交付和分布式軟件開發領域輕松采用最佳實踐. 這些應用程序是專門為雲計算體系結構(AWS,Azure,CloudFoundary等)設計的.
DevOps,持續交付,微服務和容器是開發雲原生應用程序的關鍵概念.
Spring Boot,Spring Cloud,Docker,Jenkins,Git是一些工具,可以幫助您輕松編寫Cloud-Native Application.
- 微服務
這是一種將分布式系統開發為小服務集合的體系結構方法. 每個服務負責特定的業務功能,在其自己的流程中運行,並通過HTTP REST API或消息傳遞(AMQP)進行通信.
- 開發運維
它是軟件開發人員與IT運營部門之間的合作,其目標是根據客戶的需求不斷提供高質量的軟件.
- 持續交付
所有這些都涉及不斷不斷地自動交付低風險的小批量生產變更. 這樣可以更快地收集反饋.
- 容器
容器(例如Docker)為每個微服務提供邏輯隔離,從而永遠消除了“在我的機器上運行”的問題. 與虛擬機相比,它更快,更高效.
24 您將如何使用Java開發微服務?
Spring Boot和Spring Cloud是開始使用Java語言構建微服務的一個很好的選擇. Spring Cloud中有很多模塊可以為微服務的不同設計模式提供樣板代碼,因此Spring Cloud確實可以加快開發過程. 此外,Spring Boot提供了開箱即用的支持,可將servlet容器(tomcat / jetty / undertow)嵌入可執行jar(超級jar)中,以便可以直接從命令行運行這些jar,從而無需部署war文件放入Servlet容器.
您還可以使用Docker容器將整個可執行程序包運送並部署到雲環境中. Docker還可以通過在開發階段為運行時環境提供邏輯隔離來幫助消除“在我的機器上工作”的問題. 這樣,您就可以跨本地和雲環境獲得可移植性.
25 什么是Spring Boot?
Spring Boot使得創建獨立的,基於生產級別的基於Spring的應用程序變得容易,您可以通過對Spring平台和第三方庫的獨到見解來“運行”這些應用程序,以便您大驚小怪.
Spring Boot的主要功能
- 創建獨立的Spring應用程序(12要素應用程序樣式)
- 直接嵌入Tomcat,Jetty或Undertow(無需部署WAR文件)
- 提供可靠的入門POM,以簡化您的Maven或Gradle配置
- 盡可能自動配置Spring
- 提供可用於生產的功能,例如指標,運行狀況檢查和外部化配置
- 完全沒有代碼生成,也不需要XML配置
您可以使用托管在https://start.spring.io/的在線工具為項目選擇所需的依賴項來創建Spring Boot入門項目.
任何Spring Boot應用程序的最小最小依賴關系是:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:2.0.4.RELEASE")
}
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
@Controller
@EnableAutoConfiguration
public class HelloWorldController {
@RequestMapping("/")
@ResponseBody
String home() {
return "Hello World!";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleController.class, args);
}
}
您可以直接運行此類,而無需將其部署到servlet容器中.
_有用的參考 _
- Spring Boot Project
- Spring Boot Starter
- 使用Spring Boot構建應用程序
26. 什么是API網關?
API網關是一類特殊的微服務,可滿足單個客戶端應用程序(例如android應用程序,Web應用程序,Angular JS應用程序,iPhone應用程序等)的需求,並為其提供后端資源(微服務)的單個入口,向他們提供跨領域的關注,例如安全性,監視/指標和彈性.
客戶端應用程序可以與每個請求同時訪問數十個或數百個微服務,匯總響應並將其轉換為滿足客戶端應用程序的需求. Api Gateway可以使用客戶端負載平衡器庫(Ribbon)以循環方式在實例之間分配負載. 如果需要,它也可以進行協議轉換,即HTTP到AMQP. 它也可以處理受保護資源的安全性.
API網關的功能
- Spring Cloud DiscoveryClient集成
- 請求速率限制(在Spring Boot 2.x中可用)
- 路徑改寫
- Hystrix斷路器集成,具有彈性
27 在部署期間如何實現零停機時間?
顧名思義,零停機時間部署不會在生產環境中造成停機. 這是將更改部署到生產的一種聰明方法,在任何給定時間點,至少有一項服務將對客戶可用.
- 藍綠色部署
實現此目標的一種方法是藍色/綠色部署. 在這種方法中,一次部署了一個微服務的兩個版本. 但是只有一個版本正在接受真正的請求. 一旦將新版本測試到所需的滿意度,就可以從舊版本切換到新版本.
您可以運行冒煙測試套件,以驗證該功能在新部署的版本中是否正常運行. 根據冒煙測試的結果,可以發布較新的版本,成為實時版本.
- 客戶端代碼中需要進行更改以處理零停機時間
假設您有兩個同時運行的服務實例,並且兩個實例都在Eureka注冊表中注冊. 此外,兩個實例都使用兩個不同的主機名進行部署:
/src/main/resources/application.yml
spring.application.name: ticketBooks-service
---
spring.profiles: blue
eureka.instance.hostname: ticketBooks-service -blue.example.com
---
spring.profiles: green
現在需要對books-service進行api調用的客戶端應用程序可能如下所示:
@RestController
@SpringBootApplication
@EnableDiscoveryClient
public class ClientApp {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping("/hit-some-api")
public Object hitSomeApi() {
return restTemplate().getForObject("https://ticketBooks-service/some-uri", Object.class);
}
}
現在,當ticketBooks-service-green.example.com停止升級時,它會正常關閉並從Eureka注冊表中刪除其條目. 但是,直到再次獲取注冊表(每30秒發生一次),這些更改才會反映在ClientApp中. 因此,長達30秒,ClientApp的@LoadBalanced RestTemplate可能會將請求發送到ticketBooks-service-green.example.com,即使它失敗了.
為了解決這個問題,我們可以在Ribbon客戶端負載均衡器中使用Spring Retry支持. 要啟用Spring Retry,我們需要執行以下步驟:
_添加spring-retry到build.gradle依賴項 _
compile("org.springframework.boot:spring-boot-starter-aop")
compile("org.springframework.retry:spring-retry")
現在,使用@EnableRetry批注在ClientApp中啟用spring-retry機制,如下所示:
@EnableRetry
@RestController
@SpringBootApplication
@EnableDiscoveryClient
public class ClientApp {
...
}
完成此操作后,Ribbon將自動將其自身配置為使用重試邏輯,Ribbon將重試對ticketBooks-service-green.example.com com的任何失敗請求(以循環方式). 您可以使用以下屬性來自定義此行為:
/src/main/resources/application.yml
ribbon:
MaxAutoRetries: 5
MaxAutoRetriesNextServer: 5
OkToRetryOnAllOperations: true
OkToRetryOnAllErrors: true
28. 數據庫發生更改時,如何實現零停機時間部署(藍色/綠色)?
當升級期間數據庫發生更改時,部署方案將變得復雜. 有兩種不同的方案:1.數據庫更改是向后兼容的(例如,添加新的表列)2.數據庫更改與應用程序的舊版本不兼容(例如,重命名現有的表列)
- 向后兼容更改:此方案易於實現,並且可以使用Flyway完全自動化. 我們可以添加腳本以創建新列,並且腳本將在部署時執行. 現在,在藍/綠部署期間,該應用程序的兩個版本(例如v1和v2)將連接到同一數據庫. 我們需要確保新添加的列允許空值(順便說一下,這是向后兼容更改的一部分). 如果一切順利,那么我們可以關閉舊版本v1,否則可以關閉應用程序v2.
- 不兼容的數據庫更改:這是一個棘手的情況,在回滾的情況下可能需要手動干預. 假設我們要在數據庫中將first_name列重命名為fname. 除了直接重命名,我們還可以創建一個新列fname,並將first_name的所有現有值復制到fname列中,並保持first_name列在數據庫中的狀態. 我們可以將對fname的非null檢查推遲到部署后的成功. 如果部署成功,我們需要在關閉v1之后手動將v1寫入first_name的數據遷移到新列(fname). 如果v2部署失敗,則需要執行其他操作.
在實際的生產應用程序中,復雜性可能更大,此類討論超出了本書的范圍.
29 如何在微服務架構中維護ACID?
ACID是數據庫事務管理器確保的四個主要屬性(原子性,一致性,隔離性和持久性)的首字母縮寫.
- 原子性
在涉及兩個或多個實體的事務中,所有記錄都已提交,也沒有提交.
- 一致性
數據庫事務必須僅遵循包括約束/觸發等的特定規則,以允許的方式更改受影響的數據.
- 隔離
任何進行中的事務(尚未提交)必須與其他任何事務保持隔離.
- 高可用
提交的記錄由數據庫保存,這樣即使發生故障或數據庫重新啟動,數據也可以以正確的狀態使用.
在涉及多個數據庫的分布式系統中,我們有兩種選擇來實現ACID遵從性:
- 實現ACID遵從性的一種方法是使用兩階段提交(也稱為2PC),以確保所有涉及的服務必須提交事務完成或所有事務回滾.
- 使用最終的一致性,其中不同的微服務擁有的多個數據庫最終會通過使用消息傳遞協議的異步消息傳遞而變得一致. 最終一致性是弱一致性的一種特定形式.
理想的情況下,由於微服務架構的脆弱性和復雜性,不建議使用2期提交. 通過最終的一致性,我們可以在分布式系統中達到某種程度的ACID合規性,這應該是正確的方法.
30. 什么是Spring Cloud?
Spring團隊整合了一些經過考驗的開源項目,這些項目從Pivotal,Netflix等公司整合到一個稱為Spring Cloud的Spring項目中. Spring Cloud提供了用於快速構建分布式系統的一些常見設計模式的庫和工具,包括:
| 模式類型 | 模式名稱 | Spring Cloud Library |
|---|---|---|
| 配置模式 | 分布式/版本化配置管理 | Spring Cloud Config服務器 |
| - | 核心微服務模式 | Spring Boot |
| - | 異步/分布式消息傳遞 | Spring Cloud Stream (AMQP and Kafka) |
| - | 服務間通信 | RestTemplate和Spring Cloud Feign |
| 路由模式 | 服務注冊與發現 | Spring Cloud Netflix Eureka和領事 |
| 路由模式 | 服務路由/ API網關模式 | Spring Cloud Netflix Zuul |
| 彈性模式 | 客戶端負載均衡 | Spring Cloud Netflix功能區 |
| - | 斷路器和后備模式 | Spring Cloud Netflix Hystrix |
| - | Bulkhead pattern | Spring Cloud / Spring Cloud Netflix Hystrix |
| Logging Patterns | Log Correlation | Spring Cloud Sleuth |
| - | 微服務跟蹤 | Spring Cloud Sleuth / Zipkin |
| 安全模式 | 授權與認證 | Spring Cloud Security OAuth2 |
| - | 憑證管理 | Spring Cloud Security OAuth2 / JWT |
| - | 分布式會話 | Spring Cloud OAuth2和Redis |
Spring Cloud使得為Cloud開發,部署和操作JVM應用程序變得非常容易.
