javascript
Spring Cloud –基本设置
Spring Cloud解決了分布式系統(tǒng)的常見問題。 但是,對(duì)于只使用廣為人知的整體應(yīng)用程序工作的人來說,從一開始就跳入一長(zhǎng)串為分布式服務(wù)設(shè)計(jì)的模式可能會(huì)讓人不知所措。 本文將通過實(shí)用的方法為您介紹Spring Cloud的基礎(chǔ)知識(shí)。 完成后,您不僅應(yīng)該知道如何基于Spring Cloud啟動(dòng)項(xiàng)目,還應(yīng)該了解為什么需要所有步驟以及它們解決了哪些問題。
1.第一服務(wù)
讓我們定義一下我們將使用Spring Cloud解決的問題。 該演示的目的是為分布式博客平臺(tái)奠定基礎(chǔ)。
分布式系統(tǒng)的核心組件是服務(wù),它不過是旨在專注于域的特定部分的常規(guī)應(yīng)用程序。 在一個(gè)復(fù)雜的系統(tǒng)中,可能會(huì)有數(shù)十種不同的服務(wù),但是為了清楚起見,我們僅從兩個(gè)示例開始。 第一項(xiàng)服務(wù)將照顧作者,而第二項(xiàng)服務(wù)將專注于文章。
作者服務(wù)
在我們的例子中,作者服務(wù)是使用spring-boot-starter-web創(chuàng)建的典型Spring Boot應(yīng)用程序。 目前,我們不使用Spring Cloud的任何功能。
@SpringBootApplication public class AuthorServiceApplication {public static void main(String[] args) {SpringApplication.run(AuthorServiceApplication.class, args);}}這是一個(gè)作者域類,這是我們第一個(gè)服務(wù)的主要重點(diǎn)。
class Author {private final Long id;private final String name;//…}最后,我們創(chuàng)建一個(gè)REST控制器,該控制器允許提取所有作者或根據(jù)其標(biāo)識(shí)符查找特定作者。
@RestController class AuthorController {//…@GetMappingList<Author> findAll() {//…}@GetMapping("/{id}")Author findOne(@PathVariable long id) {//…}}文章服務(wù)
第二項(xiàng)服務(wù)類似于上一項(xiàng)。 如果需要代碼示例,可以在GitHub存儲(chǔ)庫(kù)中找到它們 。
此步驟的關(guān)鍵是要認(rèn)識(shí)到,我們將域的不同部分分為較小的和松散耦合的應(yīng)用程序,而不是一個(gè)較大的應(yīng)用程序。 它給我們帶來什么? 有許多優(yōu)點(diǎn),例如,更簡(jiǎn)單的可伸縮性,彈性或更快的部署。 如果您需要更多的理論背景,建議您閱讀Sam Newman撰寫的一本很棒的書,名為Building microservices 。
2.分布式配置
如果您嘗試在一臺(tái)機(jī)器上啟動(dòng)這兩種服務(wù),則默認(rèn)的Spring Boot設(shè)置將無法實(shí)現(xiàn),因?yàn)檫@兩個(gè)應(yīng)用程序都將嘗試在端口8080上運(yùn)行。您可以自定義設(shè)置并在每個(gè)應(yīng)用程序的application.properties中選擇不同的端口。應(yīng)用程序,這對(duì)于兩個(gè)服務(wù)來說不是問題,但對(duì)于許多服務(wù)而言,可能會(huì)更成問題。
配置服務(wù)器
對(duì)于復(fù)雜的分布式系統(tǒng),明智的做法是將所有服務(wù)的配置都放在一個(gè)位置,以簡(jiǎn)化整個(gè)管理過程。 為了適合微服務(wù)系統(tǒng),這些配置將由…另一服務(wù)提供。 創(chuàng)建應(yīng)用程序,并將以下依賴項(xiàng)放入pom.xml中 。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId> </dependency>配置服務(wù)器中的主要應(yīng)用程序類與其他應(yīng)用程序沒有太大區(qū)別。 唯一的區(qū)別是之前添加的Spring Cloud依賴項(xiàng)中的@EnableConfigServer批注,該批注負(fù)責(zé)為外部配置公開API。
@SpringBootApplication @EnableConfigServer public class ConfigServerApplication {public static void main(String[] args) {SpringApplication.run(ConfigServerApplication.class, args);}}配置位置
我們將在哪里保留服務(wù)的配置? 配置服務(wù)器JAR文件中的捆綁屬性不是一個(gè)靈活的解決方案。 一些外部位置似乎是一個(gè)更好的主意。 默認(rèn)情況下,Spring Cloud使用Git存儲(chǔ)庫(kù)來管理配置。 可以在配置應(yīng)用程序的application.properties中設(shè)置Git服務(wù)器的URI地址(以及其他詳細(xì)信息)。 幸運(yùn)的是,在我們的演示中,我們不需要單獨(dú)的Git服務(wù)器。 出于測(cè)試目的,本地存儲(chǔ)庫(kù)可以正常工作。
server.port=9001 spring.application.name=config-serverspring.cloud.config.server.git.uri=file://${user.home}/configGit存儲(chǔ)庫(kù)的位置是通過spring.cloud.config.server.git.uri屬性設(shè)置的。 為了使用真實(shí)服務(wù)器,應(yīng)將值更改為不帶file:前綴的某些URL。 我們還更改了默認(rèn)端口,以避免在單臺(tái)計(jì)算機(jī)上運(yùn)行時(shí)與其他服務(wù)沖突。 此外,該應(yīng)用程序收到了自己的名稱。 目前不需要,但稍后我們將使用該名稱作為其他服務(wù)中對(duì)配置服務(wù)器的引用。
配置庫(kù)
所有服務(wù)的配置都將保留在spring.cloud.config.server.git.uri中設(shè)置的位置。 現(xiàn)在,我們可以創(chuàng)建兩個(gè)文件,專門用于以前開發(fā)的服務(wù),在其中我們將更改默認(rèn)端口并分配名稱,就像對(duì)配置服務(wù)器所做的一樣。
這是article-service.properties文件的內(nèi)容。
server.port=9003 spring.application.name=article-service此時(shí)的author-service.properties文件看起來幾乎相同。
server.port=9004 spring.application.name=author-service最后,初始化Git存儲(chǔ)庫(kù)并提交兩個(gè)創(chuàng)建的配置。
git init git add . git commit -m 'Service configs'3.服務(wù)發(fā)現(xiàn)
配置服務(wù)器已準(zhǔn)備就緒,但其他服務(wù)仍不知道其存在以及如何獲取其配置的方式。 該問題的一種可能解決方案是使用Spring Cloud Config Client將服務(wù)直接與服務(wù)器連接,該客戶端可以添加spring-cloud-starter-config依賴項(xiàng)。 主要缺點(diǎn)是我們必須在每個(gè)服務(wù)中對(duì)配置服務(wù)器的地址進(jìn)行硬編碼。 如果此服務(wù)的位置將來發(fā)生更改,或者我們想提供冗余對(duì)等方,則所有服務(wù)都需要更新。 在稱為“服務(wù)發(fā)現(xiàn)”的模式下解決了在分布式系統(tǒng)中查找其他服務(wù)的問題。
注冊(cè)表服務(wù)器
我們已經(jīng)為所有配置創(chuàng)建了服務(wù)器,這是我們的第一個(gè)基礎(chǔ)架構(gòu)服務(wù)。 同樣,現(xiàn)在我們將開發(fā)一個(gè)注冊(cè)表服務(wù)器,這是另一種基礎(chǔ)結(jié)構(gòu)服務(wù),它將充當(dāng)分布式系統(tǒng)中所有組件的地址簿。 創(chuàng)建具有以下依賴關(guān)系的新應(yīng)用程序。
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency> </dependencies>第一個(gè)負(fù)責(zé)公開注冊(cè)表API。 已經(jīng)提到了第二個(gè)依賴關(guān)系,該依賴關(guān)系用于連接我們的配置服務(wù)器,該服務(wù)器還將保存我們正在創(chuàng)建的注冊(cè)表的配置。 主應(yīng)用程序類類似于其他Spring Boot應(yīng)用程序。 我們僅添加@EnableEurekaServer批注以公開注冊(cè)表API。
@SpringBootApplication @EnableEurekaServer public class RegistryServerApplication {public static void main(String[] args) {SpringApplication.run(RegistryServerApplication.class, args);}}注冊(cè)表服務(wù)器中最后缺少的是引導(dǎo)程序配置。 配置的主要部分將由配置服務(wù)器提供服務(wù),但是我們需要描述如何找到它。 在main / resources目錄中創(chuàng)建bootstrap.properties文件,并添加下面顯示的行,這些行是配置服務(wù)器的地址和用于獲取屬性的注冊(cè)表應(yīng)用程序的名稱。
spring.cloud.config.name=registry-server spring.cloud.config.uri=http://localhost:9001公開注冊(cè)表配置
下一步是將配置添加到配置服務(wù)器監(jiān)控的Git存儲(chǔ)庫(kù)中。 創(chuàng)建一個(gè)名為Registry-server.properties的文件。 重要的是,文件名必須與注冊(cè)表服務(wù)器應(yīng)用程序中bootstrap.properties文件中的spring.cloud.config.name屬性值匹配。 最低要求的配置如下所示。 不要忘記將更改提交到Git存儲(chǔ)庫(kù)。
spring.application.name=registry-server server.port=9002eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://localhost:9002/eureka/前兩個(gè)屬性是普通Spring Boot應(yīng)用程序的典型屬性。 其他三個(gè)專用于Spring Cloud Eureka Client。 默認(rèn)情況下,每個(gè)Eureka服務(wù)器都將嘗試連接到其他對(duì)等服務(wù)器以注冊(cè)其存在。 在我們的簡(jiǎn)單演示中,我們只有一個(gè)注冊(cè)表服務(wù)器實(shí)例,但是在生產(chǎn)解決方案中,您可能會(huì)提供此類服務(wù)的某些冗余。 我們的注冊(cè)表服務(wù)器不會(huì)連接任何東西,這就是為什么我們將默認(rèn)值更改為false的原因。 注冊(cè)事件會(huì)傳播到eureka.client.serviceUrl.defaultZone中列出的所有Eureka服務(wù)器,但是盡管只有一種,因?yàn)樵谖覀冞@種情況下,我們?nèi)匀恍枰O(shè)置此屬性以覆蓋默認(rèn)值。
使用外部配置運(yùn)行注冊(cè)表
目前,我們可以同時(shí)運(yùn)行兩個(gè)服務(wù)器,以驗(yàn)證它們是否按預(yù)期工作。 由于注冊(cè)表服務(wù)器取決于配置服務(wù)器,因此需要首先啟動(dòng)它。 幾秒鐘后,也可以啟動(dòng)注冊(cè)表服務(wù)器。 如果您沒有遺漏任何步驟,則兩個(gè)應(yīng)用程序都應(yīng)運(yùn)行,日志中沒有任何錯(cuò)誤。 配置服務(wù)器應(yīng)獲取配置并在端口9002上運(yùn)行。導(dǎo)航到http:// localhost:9002 /后 ,將顯示Eureka儀表板,其中包含有關(guān)正在運(yùn)行的實(shí)例的一些詳細(xì)信息。
4.配置服務(wù)注冊(cè)
我們的注冊(cè)服務(wù)與配置服務(wù)器連接的事實(shí)并不意味著該服務(wù)器已注冊(cè)為服務(wù)。 服務(wù)的責(zé)任是將其狀態(tài)傳達(dá)給分布式寄存器。 為了連接到注冊(cè)表服務(wù),配置服務(wù)器需要以下依賴關(guān)系。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId> </dependency>它將允許我們?cè)谂渲梅?wù)器的主類中使用Eureka客戶端注釋。
@EnableEurekaClient public class ConfigServerApplication {//… }最后是注冊(cè)表服務(wù)器的地址,必須將其添加到配置服務(wù)器的application.properties中。
eureka.client.serviceUrl.defaultZone=http://localhost:9002/eureka/此時(shí),您可能開始懷疑服務(wù)器之間的通信將如何進(jìn)行。 注冊(cè)表服務(wù)器需要從配置服務(wù)器進(jìn)行配置,而同時(shí)配置服務(wù)器希望連接到注冊(cè)表以通知其存在。 他們應(yīng)該以什么順序交流?
實(shí)際上,沒有任何變化。 您首先啟動(dòng)配置服務(wù)器。 每隔幾秒鐘,它將嘗試與注冊(cè)表服務(wù)器連接并在每次失敗時(shí)打印錯(cuò)誤日志。 啟動(dòng)注冊(cè)表服務(wù)器后,它將獲取其配置并開始接受注冊(cè)。 最后,配置服務(wù)器將注冊(cè),并且不再顯示錯(cuò)誤日志。 嘗試一下以確認(rèn)它是否按預(yù)期工作。
5.配置獲取
我們的配置服務(wù)器最終可以通過本文開頭創(chuàng)建的域服務(wù)發(fā)現(xiàn)。 首先,進(jìn)行少量修改,我們需要針對(duì)作者和文章服務(wù)重復(fù)上一段的所有步驟,以允許與注冊(cè)服務(wù)進(jìn)行通信。 提醒一下,這些步驟是:
- 添加對(duì)spring-cloud-starter-eureka的依賴
- 用@EnableEurekaClient注釋主類
- 在bootstrap.properties中設(shè)置eureka.client.serviceUrl.defaultZone (不在application.properties中 )
這將允許服務(wù)與注冊(cè)表服務(wù)器進(jìn)行通信,但仍不會(huì)獲取任何配置。 為了使這一過程自動(dòng)化,我們需要在服務(wù)中提供另一個(gè)小的依賴項(xiàng)(請(qǐng)注意,注冊(cè)表服務(wù)器中使用了相同的依賴項(xiàng))。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId> </dependency>最后,我們需要在bootstrap.properties中設(shè)置一些其他詳細(xì)信息。 這是作者服務(wù)的示例文件。 類比屬性應(yīng)添加到Article服務(wù)。
spring.cloud.config.name=author-service spring.cloud.config.discovery.service-id=config-server spring.cloud.config.discovery.enabled=truespring.cloud.config.name的值必須與配置服務(wù)器提供的配置庫(kù)中的相應(yīng)屬性文件匹配。 第二個(gè)屬性用于標(biāo)識(shí)在我們的Eureka服務(wù)器中注冊(cè)的配置服務(wù)器。 更改的值必須與配置服務(wù)器中application.properties中存在的spring.application.name值匹配。 使用最后一個(gè)屬性,我們啟用配置發(fā)現(xiàn)過程。
您應(yīng)該能夠驗(yàn)證兩個(gè)服務(wù)是否都在集中式配置中定義的端口上啟動(dòng)。 如果您關(guān)閉了配置和發(fā)現(xiàn)服務(wù),請(qǐng)先啟動(dòng)它們,然后再運(yùn)行域服務(wù)。 只要所有步驟都正確完成,兩個(gè)服務(wù)都應(yīng)在配置的端口上響應(yīng)瀏覽器。 在另一種情況下,確保您不會(huì)錯(cuò)過任何步驟或?qū)⒋a與存儲(chǔ)庫(kù)中的示例進(jìn)行比較 。
6.一勞永逸,一勞永逸
目前,我們實(shí)際上可以認(rèn)為我們的基本設(shè)置已經(jīng)準(zhǔn)備就緒,但是我們將為難題添加另一部分,并了解分布式系統(tǒng)中使用的另一種模式,即服務(wù)網(wǎng)關(guān)。 顧名思義,其目的是允許客戶端使用單個(gè)訪問點(diǎn)查找所有服務(wù)。 換句話說,網(wǎng)關(guān)充當(dāng)分布式服務(wù)的路由器。
網(wǎng)關(guān)服務(wù)
讓我們?cè)诖搜菔局袆?chuàng)建最后一個(gè)Spring Boot應(yīng)用程序,并添加下面提到的依賴項(xiàng)。 唯一的新功能是spring-cloud-starter-zuul ,其中包含創(chuàng)建網(wǎng)關(guān)所需的類。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId> </dependency>除了以前添加的注釋外,應(yīng)用程序的主類還應(yīng)使用@EnableZuulProxy聲明自己為代理網(wǎng)關(guān)。
@SpringBootApplication @EnableZuulProxy @EnableEurekaClient public class GatewayServiceApplication {public static void main(String[] args) {SpringApplication.run(GatewayServiceApplication.class, args);}}該應(yīng)用程序還需要bootstrap.properties文件,該文件的值類似于先前配置的域服務(wù)。 這里沒有什么新東西需要解釋。
spring.cloud.config.name=gateway-service spring.cloud.config.discovery.service-id=config-server spring.cloud.config.discovery.enabled=trueeureka.client.serviceUrl.defaultZone=http://localhost:9002/eureka/配置獲取
就像其他常規(guī)服務(wù)一樣,網(wǎng)關(guān)依賴于配置服務(wù)器管理的Git存儲(chǔ)庫(kù)中存儲(chǔ)的配置。 創(chuàng)建一個(gè)名為gateway-service.properties的文件,使用以下值設(shè)置其內(nèi)容,然后將更改提交到配置庫(kù)。
spring.application.name=gateway-service server.port=8080zuul.routes.author-service.path=/authors/**zuul.routes.article-service.path=/articles/**我們已經(jīng)知道前兩個(gè)值。 另外兩個(gè)更有趣。 在這里,我們定義對(duì)于給定的URL模式,到網(wǎng)關(guān)的所有請(qǐng)求都應(yīng)轉(zhuǎn)發(fā)到由其名稱標(biāo)識(shí)的服務(wù)。 請(qǐng)注意,我們不會(huì)將網(wǎng)關(guān)與這些服務(wù)的任何特定主機(jī)地址耦合。 網(wǎng)關(guān)將使用先前創(chuàng)建的發(fā)現(xiàn)服務(wù)找到它們。
最終基本設(shè)置驗(yàn)證
啟動(dòng)網(wǎng)關(guān)之后,應(yīng)用程序應(yīng)在端口8080上進(jìn)行偵聽。嘗試使用配置的映射訪問這兩個(gè)域服務(wù):
http:// localhost:8080 / articles
http:// localhost:8080 / authors
網(wǎng)關(guān)模式使我們能夠?qū)PI的客戶端與運(yùn)行服務(wù)的特定主機(jī)分離。 只有網(wǎng)關(guān)的地址必須與客戶端共享。 網(wǎng)關(guān)還可以照顧重復(fù)服務(wù)的負(fù)載平衡,但是讓我們將這個(gè)話題再留一遍。
7.總結(jié)
乍一看,基本的Spring Cloud設(shè)置似乎非常復(fù)雜,尤其是與典型的整體應(yīng)用程序基礎(chǔ)相比。 還有許多創(chuàng)建系統(tǒng)的構(gòu)件。 但是,每個(gè)組件在設(shè)計(jì)時(shí)都考慮了“單一責(zé)任主體”。 我們了解了微服務(wù)體系結(jié)構(gòu)中使用的三種基本模式,即服務(wù)發(fā)現(xiàn),分布式配置和服務(wù)網(wǎng)關(guān)。 他們每個(gè)人都有一個(gè)專用的應(yīng)用程序,僅專注于單個(gè)任務(wù)。 劃分職責(zé)是微服務(wù)體系結(jié)構(gòu)的主要要素,即使我們創(chuàng)建的小型演示在實(shí)踐中也極大地描述了這個(gè)想法。
翻譯自: https://www.javacodegeeks.com/2017/10/spring-cloud-basic-setup.html
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud –基本设置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AOC 爱攻发布 16G3 便携显示器:
- 下一篇: (金盾抗ddos系统)