溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)

發(fā)布時(shí)間:2021-12-04 13:54:30 來源:億速云 閱讀:112 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu),相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

微服務(wù)架構(gòu)模式的核心在于如何識別服務(wù)的邊界,設(shè)計(jì)出合理的微服務(wù)。

但如果要將微服務(wù)架構(gòu)運(yùn)用到生產(chǎn)項(xiàng)目上,并且能夠發(fā)揮該架構(gòu)模式的重要作用,則需要微服務(wù)框架的支持。

怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)

在 Java 生態(tài)圈,目前使用較多的微服務(wù)框架就是集成了包括 Netflix OSS 以及 Spring Cloud。

它包括:

  • Spring Cloud Config:配置管理工具,支持使用 Git 存儲配置內(nèi)容,可以實(shí)現(xiàn)應(yīng)用配置的外部化存儲,支持客戶端配置信息刷新、加密/解密配置內(nèi)容等。

  • Spring Cloud Netflix:對 Netflix OSS 進(jìn)行了整合。

其中又包括:

Eureka:服務(wù)治理組件,包含服務(wù)注冊中心、服務(wù)注冊與發(fā)現(xiàn)。

Hystrix:容器管理組件,實(shí)現(xiàn)斷路器模式,倘若依賴的服務(wù)出現(xiàn)延遲或故障,則提供強(qiáng)大的容錯(cuò)功能。

Ribbon:客戶端負(fù)載均衡的服務(wù)調(diào)用組件。

Feign:基于 Ribbon 和 Hystrix 的聲明式服務(wù)調(diào)用組件。

Zuul:網(wǎng)關(guān)組件,提供智能路由、訪問過濾等功能。

Archaius:外部化配置組件。

  • Spring Cloud Bus:事件、消息總線。

  • Spring Cloud Cluster:針對 ZooKeeper、Redis、Hazelcast、Consul 的選舉算法和通用狀態(tài)模式的實(shí)現(xiàn)。

  • Spring Cloud Cloudfoundry:與 Pivotal Cloudfoundry 的整合支持。

  • Spring Cloud Consul:服務(wù)發(fā)現(xiàn)與配置管理工具。

  • Spring Cloud Stream:通過 Redis、Rabbit 或者 Kafka 實(shí)現(xiàn)的消息驅(qū)動的微服務(wù)。

  • Spring Cloud AWS:簡化和整合 Amazon Web Service。

  • Spring Cloud Security:安全工具包,提供 Zuul 代理中對 OAuth3 客戶端請求的中繼器。

  • Spring Cloud Sleuth:Spring Cloud 應(yīng)用的分布式跟蹤實(shí)現(xiàn),可以整合 Zipkin。

  • Spring Cloud ZooKeeper:基于 ZooKeeper 的服務(wù)發(fā)現(xiàn)與配置管理組件。

  • Spring Cloud Starters:Spring Cloud 的基礎(chǔ)組件,是基于 Spring Boot 風(fēng)格項(xiàng)目的基礎(chǔ)依賴模塊。

  • Spring Cloud CLI:用于在 Groovy 中快速創(chuàng)建 Spring Cloud 應(yīng)用的 Spring Boot CLI 插件。

服務(wù)治理

當(dāng)一個(gè)系統(tǒng)的微服務(wù)數(shù)量越來越多的時(shí)候,我們就需要對服務(wù)進(jìn)行治理,提供統(tǒng)一的服務(wù)注冊中心,然后在其框架下提供發(fā)現(xiàn)服務(wù)的功能。

這樣就避免了對多個(gè)微服務(wù)的配置,以及微服務(wù)之間以及與客戶端之間的耦合。

Spring Cloud Eureka 是對 Netflix Eureka 的包裝,用以實(shí)現(xiàn)服務(wù)注冊與發(fā)現(xiàn)。

Eureka 服務(wù)端即服務(wù)注冊中心,支持高可用配置。它依托強(qiáng)一致性提供良好的服務(wù)實(shí)例可用性,并支持集群模式部署。

Eureka 客戶端則負(fù)責(zé)處理服務(wù)的注冊與發(fā)現(xiàn)??蛻舳朔?wù)通過 annotation 與參數(shù)配置的方式,嵌入在客戶端應(yīng)用程序代碼中。

在運(yùn)行應(yīng)用程序時(shí),Eureka 客戶端向注冊中心注冊自身提供的服務(wù),并周期性地發(fā)送心跳更新它的服務(wù)租約。

搭建服務(wù)注冊中心

服務(wù)注冊中心是一個(gè)獨(dú)立部署的服務(wù)(你可以認(rèn)為它也是一個(gè)微服務(wù)),所以需要單獨(dú)為它創(chuàng)建一個(gè)項(xiàng)目,并在 pom.xml 中添加 Eureka 的依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>

創(chuàng)建 Spring Boot Application:

@EnableEurekaServer @SpringBootApplication public class Application {     public static void main(String[] args) {         new SpringApplicationBuilder(Application.class).web(true).run(args);     } }

注冊服務(wù)提供者

要讓自己編寫的微服務(wù)能夠注冊到 Eureka 服務(wù)器中,需要在服務(wù)的 Spring Boot Application 中添加 @EnableDiscoveryClient 注解,如此才能讓 Eureka 服務(wù)器發(fā)現(xiàn)該服務(wù)。

當(dāng)然,pom.xml 文件中也需要添加相關(guān)依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>

同時(shí),我們還需要為服務(wù)命名,并指定地址。這些信息都可以在 application.properties 配置文件中配置:

spring.application.name=demo-service  eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

說明:Spring 更推薦使用 yml 文件來維護(hù)系統(tǒng)的配置,yml 文件可以體現(xiàn)出配置節(jié)的層次關(guān)系,表現(xiàn)力比單純的 key-value 形式更好。

如果結(jié)合使用后面講到的 Spring Cloud Config,則客戶端的配置文件必須命名為 bootstrap.properties 或者 bootstrap.yml。

與上述配置相同的 yml 文件配置為:

spring:   application:     name: demo-service  eureka:   client:     serviceUrl:        defaultZone: http://localhost:1111/eureka/

服務(wù)發(fā)現(xiàn)與消費(fèi)

在微服務(wù)架構(gòu)下,許多微服務(wù)可能會扮演雙重身份:

  • 一方面它是服務(wù)的提供者

  • 另一方面它又可能是服務(wù)的消費(fèi)者

注冊在 Eureka Server 中的微服務(wù)可能會被別的服務(wù)消費(fèi)。此時(shí),就相當(dāng)于在服務(wù)中創(chuàng)建另一個(gè)服務(wù)的客戶端,并通過 RestTemplate 發(fā)起對服務(wù)的調(diào)用。

為了更好地提高性能,可以在服務(wù)的客戶端引入 Ribbon,作為客戶端負(fù)載均衡。

現(xiàn)在假定我們要為 demo-service 創(chuàng)建一個(gè)服務(wù)消費(fèi)者 demo-consumer。該消費(fèi)者自身也是一個(gè) Spring Boot 微服務(wù),同時(shí)也能夠被 Eureka 服務(wù)器注冊。

這時(shí),就需要在該服務(wù)的 pom.xml 中添加 Eureka 與 Ribbon 的依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>

然后在主應(yīng)用類 ConosumerApplication 中注入 RestTemplate,并引入 @LoadBalanced 注解開啟客戶端負(fù)載均衡:

@EnableDiscoveryClient @SpringBootApplication public class ConsumerApplication {     @Bean     @LoadBalanced     RestTemplate restTemplate() {         return new RestTemplate();     }     public static void main(String[] args) {         SpringApplication.run(ConsumerApplication.class, args)     } }

假設(shè)消費(fèi) demo-service 的客戶端代碼寫在 demo-consumer 服務(wù)的其中一個(gè) Controller 中:

@RestController public class ConsumerController {     @Autowired     RestTemplate restTemplate;      @RequestMapping(value = "/demo-consumer", method = RequestMethod.Get)     public String helloConsumer() {         return restTemplate.getForEntity("http://demo-service/demo", String.class).getBody();      } }

通過 RestTemplate 就可以發(fā)起對 demo-service 的消費(fèi)調(diào)用。

聲明式服務(wù)調(diào)用

通過 Ribbon 和 Hystrix 可以實(shí)現(xiàn)對微服務(wù)的調(diào)用以及容錯(cuò)保護(hù),但 Spring Cloud 還提供了另一種更簡單的聲明式服務(wù)調(diào)用方式,即 Spring Cloud Feign。

Feign 實(shí)際上就是對 Ribbon 與 Hystrix 的進(jìn)一步封裝。通過 Feign,我們只需創(chuàng)建一個(gè)接口并用 annotation 的方式配置,就可以完成對服務(wù)供應(yīng)方的接口(REST API)綁定。

假設(shè)我們有三個(gè)服務(wù):

  • Notification Service

  • Account Service

  • Statistics Service

服務(wù)之間的依賴關(guān)系如下圖所示:

怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)

要使用 Feign 來完成聲明式的服務(wù)調(diào)用,需要在作為調(diào)用者的服務(wù)中創(chuàng)建 Client。

Client 通過 Eureka Server 調(diào)用注冊的對應(yīng)服務(wù),這樣可以解除服務(wù)之間的耦合。

結(jié)構(gòu)如下圖所示:

怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)

為了使用 Feign,需要對應(yīng)微服務(wù)的 pom.xml 文件中添加如下依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-feign</artifactId> </dependency>

同時(shí),還需要在被消費(fèi)的微服務(wù) Application 中添加 @EnableFeignClients 注解。

例如在 Statistics 服務(wù)的應(yīng)用程序類中:

@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class StatisticsApplication {     public static void main(String[] args) {         SpringApplication.run(StatisticsApplication.class, args);     } }

由于 Account 服務(wù)需要調(diào)用 Statistics 服務(wù),因此需要在 Account 服務(wù)項(xiàng)目中增加對應(yīng)的 Client 接口:

@FeignClient(name = "statistics-service") public interface StatisticsServiceClient {      @RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)     void updateStatistics(@PathVariable("accountName") String accountName, Account account);  }

StatisticsServiceClient 接口的 updateStatistics() 方法會調(diào)用 URI 為 /statistics/{accountName} 的 REST 服務(wù),且 HTTP 動詞為 put。

這個(gè)服務(wù)對應(yīng)的就是 Statistics Service 中 StatisticsController 類中的 saveStatistics() 方法:

@RestController public class StatisticsController {      @Autowired     private StatisticsService statisticsService;      @RequestMapping(value = "/{accountName}", method = RequestMethod.PUT)     public void saveStatistics(@PathVariable String accountName, @Valid @RequestBody Account account) {         statisticsService.save(accountName, account);     } }

在 Account 服務(wù)中,如果要調(diào)用 Statistics 服務(wù),都應(yīng)該通過 StatisticsServiceClient 接口進(jìn)行調(diào)用。

例如,Account 服務(wù)中的 AccountServiceImpl 要調(diào)用 updateStatistics() 方法,就可以在該類的實(shí)現(xiàn)中通過 @autowired 注入 StatisticsServiceClient 接口:

@Service public class AccountServiceImpl implements AccountService {     @Autowired     private StatisticsServiceClient statisticsClient;      @Autowired     private AccountRepository repository;      @Override     public void saveChanges(String name, Account update) {          //...         statisticsClient.updateStatistics(name, account);     } }

Notification 服務(wù)對 Account 服務(wù)的調(diào)用如法炮制。

服務(wù)容錯(cuò)保護(hù)

在微服務(wù)架構(gòu)中,微服務(wù)之間可能存在依賴關(guān)系,例如 Notification Service 會調(diào)用 Account Service,Account Service 調(diào)用 Statistics Service。

真實(shí)產(chǎn)品中,微服務(wù)之間的調(diào)用會更加尋常。倘若上游服務(wù)出現(xiàn)了故障,就可能會因?yàn)橐蕾囮P(guān)系而導(dǎo)致故障的蔓延,最終導(dǎo)致整個(gè)系統(tǒng)的癱瘓。

Spring Cloud Hystrix 通過實(shí)現(xiàn)斷路器(Circuit Breaker)模式以及線程隔離等功能,實(shí)現(xiàn)服務(wù)的容錯(cuò)保護(hù)。

仍然參考前面的例子,現(xiàn)在系統(tǒng)的微服務(wù)包括:

  • 上游服務(wù):demo-service

  • 下游服務(wù):demo-consumer

  • Eureka 服務(wù)器:eureka-server

假設(shè)上游服務(wù)可能會出現(xiàn)故障,為保證系統(tǒng)的健壯性,需要在下游服務(wù)中加入容錯(cuò)包含功能。

首先需要在 demo-consumer 服務(wù)中添加對 Hystrix 的依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>

然后在 demo-consumer 的應(yīng)用程序類中加入 @EnableCircuitBreaker 開啟斷路器功能:

@EnableCircuitBreaker @EnableDiscoveryClient @SpringBootApplication public class ConsumerApplication {     @Bean     @LoadBalanced     RestTemplate restTemplate() {         return new RestTemplate();     }     public static void main(String[] args) {         SpringApplication.run(ConsumerApplication.class, args)     } }

注意:Spring Cloud 提供了 @SpringCloudApplication 注解簡化如上代碼。該注解事實(shí)上已經(jīng)包含了前面所述的三個(gè)注解。

@SpringCloudApplication 注解的定義如下所示:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication {}

接下來,需要引入一個(gè)新的服務(wù)類來封裝 Hystrix 提供的斷路器保護(hù)功能,主要是定義當(dāng)故障發(fā)生時(shí)需要執(zhí)行的回調(diào)邏輯,即代碼中指定的 fallbackMethod:

@Service public class ConsumerService {     @Autowired     RestTemplate restTemplate;      @HystrixCommand(fallbackMethod = "consumerFallback")     public String consume() {         return restTemplate.getForEntity("http://demo-service/demo", String.class).getBody();      }      public String consumerFallback() {         return "error";     } }  @RestController public class ConsumerController {     @Autowired     ConsumerService consumerService;      @RequestMapping(value = "/demo-consumer", method = RequestMethod.Get)     public String helloConsumer() {         return consumerService.consume();      } }

服務(wù)監(jiān)控

微服務(wù)架構(gòu)將服務(wù)的粒度分解的足夠細(xì),這使得它在保證服務(wù)足夠靈活、足夠獨(dú)立的優(yōu)勢下,也帶來了管理和監(jiān)控上的挑戰(zhàn),服務(wù)與服務(wù)之間的依賴也變得越來越復(fù)雜。因此,對服務(wù)健康度和運(yùn)行指標(biāo)的監(jiān)控就變得非常重要。

Hystrix 提供了 Dashboard 用以監(jiān)控 Hystrix 的各項(xiàng)指標(biāo)信息。為了監(jiān)控整個(gè)系統(tǒng)的微服務(wù),我們需要為 Hystrix Dashboard 建立一個(gè) Spring Boot 微服務(wù)。

在該服務(wù)項(xiàng)目的 pom 文件中,添加如下依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> <dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-actuator</artifactId> </dependency>

服務(wù)的 Application 類需要添加 @EnableHystrixDashboard,以啟用 Hystrix Dashboard 功能。

同時(shí),可能需要根據(jù)實(shí)際情況修改 application.properties 配置文件,例如選擇可用的端口號等。

如果要實(shí)現(xiàn)對集群的監(jiān)控,則需要加入 Turbine。

API 網(wǎng)關(guān)

理論上,客戶端可以直接向每個(gè)微服務(wù)直接發(fā)送請求。但是這種方式是存在挑戰(zhàn)和限制的,調(diào)用者需要知道所有端點(diǎn)的地址,分別對每一段信息執(zhí)行 http 請求,然后將結(jié)果合并到客戶端。

一般而言,針對微服務(wù)架構(gòu)模式的系統(tǒng),采用的都是前后端分離的架構(gòu)。為了明顯地隔離開前端與后端的邊界,我們通??梢詫iT為前端的消費(fèi)者定義更加粗粒度的 Open Service。

這些 Open Service 是對外的 RESTful API 服務(wù),可以通過 F5、Nginx 等網(wǎng)絡(luò)設(shè)備或工具軟件實(shí)現(xiàn)對各個(gè)微服務(wù)的路由與負(fù)載均衡,并公開給外部的客戶端調(diào)用(注意,內(nèi)部微服務(wù)之間的調(diào)用并不需要通過 Open Service)。

這種對外公開的 Open Service 通常又被稱為邊緣服務(wù)(edge service)。

如果這些 Open Service 需要我們自己去開發(fā)實(shí)現(xiàn)并進(jìn)行服務(wù)的運(yùn)維,在系統(tǒng)規(guī)模不斷增大的情況下,會變得越來越困難。

例如,當(dāng)增加了新的微服務(wù)又或者 IP 地址發(fā)生變動時(shí),都需要運(yùn)維人員手工維護(hù)這些路由規(guī)則與服務(wù)實(shí)例列表。

又例如針對所有垂直分隔的微服務(wù),不可避免存在重用的橫切關(guān)注點(diǎn),例如用戶身份認(rèn)證、授權(quán)或簽名校驗(yàn)等機(jī)制。

我們不能在所有微服務(wù)中都去添加這些相同的功能,因?yàn)檫@會造成橫切關(guān)注點(diǎn)的冗余。

解決的辦法是引入 API 網(wǎng)關(guān)(API Gateway)。它是系統(tǒng)的單個(gè)入口點(diǎn),用于通過將請求路由到適當(dāng)?shù)暮蠖朔?wù)或者通過調(diào)用多個(gè)后端服務(wù)并聚合結(jié)果來處理請求。

此外,它還可以用于認(rèn)證、insights、壓力測試、金絲雀測試(canary testing)、服務(wù)遷移、靜態(tài)響應(yīng)處理和主動變換管理。

Spring Cloud 為 API 網(wǎng)關(guān)提供的解決方案就是 Spring Cloud Zuul,它是對 Netflix Zuul 的包裝。

路由規(guī)則與服務(wù)實(shí)例維護(hù)

Zuul 解決路由規(guī)則與服務(wù)實(shí)例維護(hù)的方法是通過 Spring Cloud Eureka。

API Gateway 自身就是一個(gè) Spring Boot 服務(wù),該服務(wù)自身被注冊為 Eureka 服務(wù)治理下的應(yīng)用,同時(shí)它會從 Eureka 中獲得所有其他微服務(wù)的實(shí)例信息。

這樣的設(shè)計(jì)符合 DRY 原則,因?yàn)?Eureka 已經(jīng)維護(hù)了一套服務(wù)實(shí)例信息,Zuul 直接重用了這些信息,無需人工介入。

對于路由規(guī)則,Zuul 默認(rèn)會將服務(wù)名作為 ContextPath 創(chuàng)建路由映射,基本上這種路由映射機(jī)制就可以滿足微服務(wù)架構(gòu)的路由需求。

倘若需要一些特殊的配置,Zuul 也允許我們自定義路由規(guī)則,可以通過在 API 網(wǎng)關(guān)的 Application 類中創(chuàng)建 PatternServiceRouteMapper 來定義自己的規(guī)則。

橫切關(guān)注點(diǎn)

諸如授權(quán)認(rèn)證、簽名校驗(yàn)等業(yè)務(wù)邏輯本身與微服務(wù)應(yīng)用所要處理的業(yè)務(wù)邏輯沒有直接關(guān)系,我們將這些可能橫跨多個(gè)微服務(wù)的功能稱為“橫切關(guān)注點(diǎn)”。這些橫切關(guān)注點(diǎn)往往會作為“裝飾”功能在服務(wù)方法的前后被調(diào)用。

Spring Cloud Zuul 提供了一套過濾器機(jī)制,允許開發(fā)者創(chuàng)建各種過濾器,并指定哪些規(guī)則的請求需要執(zhí)行哪個(gè)過濾器。

自定義的過濾器繼承自 ZuulFilter 類。例如我們要求客戶端發(fā)過來的請求在路由之前需要先驗(yàn)證請求中是否包含 accessToken 參數(shù)。

如果有就進(jìn)行路由,否則就拒絕,并返回 401 Unauthorized 錯(cuò)誤,則可以定義 AccessFilter 類:

public class AccessFilter extends ZuulFilter {     private static Logger log = LoggerFactory.getLogger(AccessFilter.class);      @Override     public String filterType() {         return "pre"     }      @Override     public int filterOrder() {         return 0;     }      @Override     public boolean shouldFilter() {         return true;     }      @Override     public Object run() {         RequestContext ctx = RequestContext.getCurrentContext();         HttpServletRequest request = ctx.getRequest();          log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());          Object accessToken = request.getParameter("accessToken");         if (accessToken == null) {             log.warn("access token is empty");             ctx.setSendZuulResponse(false);             ctx.setResponseStatusCode(401);             return null;         }         log.info("access token ok");         return null;     } }

要讓該自定義過濾器生效,還需要在 Zuul 服務(wù)的 Application 中創(chuàng)建具體的 Bean:

@EnableZuulProxy @SpringCloudApplication public class ZuulApplication {     public static void main(String[] args) {         new SpringApplicatonBuilder(ZuulApplication.class).web(true).run(args);     }      @Bean     public AccessFilter accessFilter() {         return new AccessFilter();     } }

Zuul 一共提供了四種過濾器:

  • pre filter

  • routing filter

  • post filter

  • error filter

下圖來自官網(wǎng),它展現(xiàn)了客戶端請求到達(dá) Zuul API 網(wǎng)關(guān)的生命周期與過濾過程:

怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)

通過 starter 添加 Zuul 的依賴時(shí),自身包含了 spring-cloud-starter-hystrix 與 spring-cloud-starter-ribbon 模塊的依賴,因此 Zuul 自身就擁有線程隔離與斷路器的服務(wù)容錯(cuò)功能,以及客戶端負(fù)載均衡。

但是,倘若我們使用 path 與 url 的映射關(guān)系來配置路由規(guī)則,則路由轉(zhuǎn)發(fā)的請求并不會采用 HystrixCommand 來包裝,因而這類路由是沒有服務(wù)容錯(cuò)與客戶端負(fù)載均衡作用的。

所以在使用 Zuul 時(shí),應(yīng)盡量使用 path 和 serviceId 的組合對路由進(jìn)行配置。

分布式配置中心

為什么要引入一個(gè)分布式配置中心?一個(gè)微服務(wù)就需要至少一個(gè)配置文件,怎么管理分散在各個(gè)微服務(wù)中的配置文件呢?如果微服務(wù)采用的是不同的技術(shù)棧,如何來統(tǒng)一微服務(wù)的配置呢?

微服務(wù)是部署在不同的節(jié)點(diǎn)中,顯然我們無法在單機(jī)中實(shí)現(xiàn)對分布式節(jié)點(diǎn)的配置管理。這就是引入 Spring Cloud Config 的目的。

Spring Cloud Config 提供了服務(wù)端和客戶端支持。服務(wù)端是一個(gè)獨(dú)立的微服務(wù),同樣可以注冊到 Eureka 服務(wù)器中。

每個(gè)需要使用分布式配置中心的微服務(wù)都是 Spring Cloud Config 的客戶端。

Spring Cloud Config 默認(rèn)實(shí)現(xiàn)基于 Git 倉庫,既可以進(jìn)行版本管理,還可以通過本地 Git 庫起到緩存作用。

Spring Cloud Config 不限于基于 Spring Cloud 開發(fā)的系統(tǒng),而是可以用于任何語言開發(fā)的程序,并支持自定義實(shí)現(xiàn)。

配置中心服務(wù)端

Spring Cloud Config Server 作為配置中心服務(wù)端,提供如下功能:

  • 拉取配置時(shí)更新 Git 倉庫副本,保證是***結(jié)果。

  • 支持?jǐn)?shù)據(jù)結(jié)構(gòu)豐富,yml,json,properties 等。

  • 配合 Eureke 可實(shí)現(xiàn)服務(wù)發(fā)現(xiàn),配合 cloud bus 可實(shí)現(xiàn)配置推送更新。

  • 配置存儲基于 Git 倉庫,可進(jìn)行版本管理。

  • 簡單可靠,有豐富的配套方案。

建立一個(gè) Config 服務(wù),需要添加如下依賴:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-config-server</artifactId> </dependency>

服務(wù)的 Application 類需要添加 @EnableConfigServer 注解:

@SpringBootApplication @EnableConfigServer public class ConfigApplication {      public static void main(String[] args) {         SpringApplication.run(ConfigApplication.class, args);     } }

配置服務(wù)的基本信息和 Git 倉庫的信息放在 application.yml 文件中:

spring:   cloud:     config:       server:         git:             uri: http://localhost/workspace/springcloud-demo             username: user             password: password  server:   port: 8888  security:   user:     password: ${CONFIG_SERVICE_PASSWORD}

Git 庫與配置服務(wù)

在 Config 服務(wù)中配置了 Git 服務(wù)器以及 Git 庫的信息后,我們就可以在 Git 庫中提交配置文件。

存儲在Git 庫中配置文件的名字以及分支名(默認(rèn)為 master 分支)會組成訪問 Config 服務(wù)的 URI。

假設(shè)有一個(gè)服務(wù)為 Notification 服務(wù),則它在配置中心服務(wù)端的配置文件為 notification-dev.yml,內(nèi)容如下:

devMode:  true spring:     application:         name: notification     jdbc:         host: localhost         port: 3306         user: root         password: 123456 logging:     file: demo

配置中心客戶端

需要讀取配置中心服務(wù)端信息的微服務(wù)都是配置中心的客戶端,為了能夠讀取配置服務(wù)端的信息,這些微服務(wù)需要:

  • 在 pom 中添加對 spring-cloud-starter-config 的依賴。

  • 在 bootstrap.properties 或者 bootstrap.yml 中配置獲取配置的 config-server 位置。

例如,Account 服務(wù)的配置是由 Spring Cloud Config 進(jìn)行管理的。在它的資源目錄下,提供了 bootstrap.yml 配置文件,內(nèi)容如下所示:

spring:   application:     name: account-service   cloud:     config:       uri: http://config:8888       fail-fast: true       password: ${CONFIG_SERVICE_PASSWORD}       username: user

注意,該配置文件除了配置了該 Account 服務(wù)應(yīng)用的 name 之外,主要是支持該應(yīng)用獲得配置服務(wù)端的信息。

微服務(wù)自身的配置信息則統(tǒng)一放到配置中心服務(wù)端的文件中,并由 Git 庫進(jìn)行管理。

例如,Account 服務(wù)的詳細(xì)配置在配置中心服務(wù)端的 account-dev.yml 文件中:

security:   oauth3:     client:       clientId: account-service       clientSecret: ${ACCOUNT_SERVICE_PASSWORD}       accessTokenUri: http://auth-service:5000/uaa/oauth/token       grant-type: client_credentials       scope: server  spring:   data:     mongodb:       host: account-mongodb       username: user       password: ${MONGODB_PASSWORD}       database: piggymetrics       port: 27017  server:   context-path: /accounts   port: 6000

Spring Cloud Config 通過 Git 實(shí)現(xiàn)分布式的配置管理。當(dāng)配置中心服務(wù)端的配置信息發(fā)生變更時(shí),各個(gè)作為配置客戶端的微服務(wù)會向 Git 庫提交 pull 更新,獲得***的配置信息。

當(dāng)然,Spring Cloud Config 還可以使用 SVN 庫進(jìn)行配置管理,也支持簡單的本地文件系統(tǒng)的存儲方式。

此時(shí)需要將 spring.profiles.active 設(shè)置為 native,并設(shè)置搜索配置文件的路徑。如果不配置路徑,默認(rèn)在 src/main/resources 目錄下搜索。

如下配置文件:

spring:   cloud:     config:       server:         native:           search-locations: classpath:/shared   profiles:     active: native

搜索路徑放在 classpath 下的 shared 目錄下,那么在代碼中,目錄就是 resources/shared。

如果使用本地文件系統(tǒng)管理配置文件,則無法支持分布式配置管理以及版本管理,因此在生產(chǎn)系統(tǒng)下,還是推薦使用 Git 庫的方式。

以上是“怎么使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI