成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

如何使用SpringCloud構(gòu)建微服務(wù)架構(gòu)?-創(chuàng)新互聯(lián)

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

創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站設(shè)計(jì)、做網(wǎng)站與策劃設(shè)計(jì),平壩網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:平壩等地區(qū)。平壩做網(wǎng)站價(jià)格咨詢:18982081108

如何使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)?

但如果要將微服務(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 存儲(chǔ)配置內(nèi)容,可以實(shí)現(xiàn)應(yīng)用配置的外部化存儲(chǔ),支持客戶端配置信息刷新、加密/解密配置內(nèi)容等。

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

其中又包括:

Eureka:服務(wù)治理組件,包含服務(wù)注冊(cè)中心、服務(wù)注冊(cè)與發(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:針對(duì) 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ū)動(dòng)的微服務(wù)。

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

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

  • 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í)候,我們就需要對(duì)服務(wù)進(jìn)行治理,提供統(tǒng)一的服務(wù)注冊(cè)中心,然后在其框架下提供發(fā)現(xiàn)服務(wù)的功能。

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

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

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

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

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

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

服務(wù)注冊(cè)中心是一個(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);     } }

注冊(cè)服務(wù)提供者

要讓自己編寫的微服務(wù)能夠注冊(cè)到 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ù)可能會(huì)扮演雙重身份:

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

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

注冊(cè)在 Eureka Server 中的微服務(wù)可能會(huì)被別的服務(wù)消費(fèi)。此時(shí),就相當(dāng)于在服務(wù)中創(chuàng)建另一個(gè)服務(wù)的客戶端,并通過 RestTemplate 發(fā)起對(duì)服務(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ù)器注冊(cè)。

這時(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ā)起對(duì) demo-service 的消費(fèi)調(diào)用。

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

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

Feign 實(shí)際上就是對(duì) Ribbon 與 Hystrix 的進(jìn)一步封裝。通過 Feign,我們只需創(chuàng)建一個(gè)接口并用 annotation 的方式配置,就可以完成對(duì)服務(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)用注冊(cè)的對(duì)應(yīng)服務(wù),這樣可以解除服務(wù)之間的耦合。

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

如何使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)?

為了使用 Feign,需要對(duì)應(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)目中增加對(duì)應(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() 方法會(huì)調(diào)用 URI 為 /statistics/{accountName} 的 REST 服務(wù),且 HTTP 動(dòng)詞為 put。

這個(gè)服務(wù)對(duì)應(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ù)對(duì) Account 服務(wù)的調(diào)用如法炮制。

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

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

真實(shí)產(chǎn)品中,微服務(wù)之間的調(diào)用會(huì)更加尋常。倘若上游服務(wù)出現(xiàn)了故障,就可能會(huì)因?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ù)可能會(huì)出現(xiàn)故障,為保證系統(tǒng)的健壯性,需要在下游服務(wù)中加入容錯(cuò)包含功能。

首先需要在 demo-consumer 服務(wù)中添加對(duì) 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)勢(shì)下,也帶來了管理和監(jiān)控上的挑戰(zhàn),服務(wù)與服務(wù)之間的依賴也變得越來越復(fù)雜。因此,對(duì)服務(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 配置文件,例如選擇可用的端口號(hào)等。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

對(duì)于路由規(guī)則,Zuul 默認(rèn)會(huì)將服務(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)往往會(huì)作為“裝飾”功能在服務(wù)方法的前后被調(diào)用。

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

自定義的過濾器繼承自 ZuulFilter 類。例如我們要求客戶端發(fā)過來的請(qǐng)求在路由之前需要先驗(yàn)證請(qǐng)求中是否包含 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)了客戶端請(qǐng)求到達(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ā)的請(qǐng)求并不會(huì)采用 HystrixCommand 來包裝,因而這類路由是沒有服務(wù)容錯(cuò)與客戶端負(fù)載均衡作用的。

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

分布式配置中心

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

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

Spring Cloud Config 提供了服務(wù)端和客戶端支持。服務(wù)端是一個(gè)獨(dú)立的微服務(wù),同樣可以注冊(cè)到 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)配置推送更新。

  • 配置存儲(chǔ)基于 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 庫中提交配置文件。

存儲(chǔ)在Git 庫中配置文件的名字以及分支名(默認(rèn)為 master 分支)會(huì)組成訪問 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 中添加對(duì) 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ù)會(huì)向 Git 庫提交 pull 更新,獲得最新的配置信息。

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

此時(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 庫的方式。

總結(jié)

在實(shí)施微服務(wù)時(shí),我們可以將微服務(wù)視為兩個(gè)不同的邊界:

  • 一個(gè)是與前端 UI 的通信,稱為 Open Service(Edge Service),通過引入 API Gateway 來實(shí)現(xiàn)與前端UI的通信。

  • 另一個(gè)是在邊界內(nèi)業(yè)務(wù)微服務(wù)之間的通信,通過 Feign 實(shí)現(xiàn)微服務(wù)之間的協(xié)作。

所有的微服務(wù)都會(huì)通過 Eureka 來完成微服務(wù)的注冊(cè)與發(fā)現(xiàn)。一個(gè)典型的基于 Spring Cloud 的微服務(wù)架構(gòu)如下所示:

如何使用Spring Cloud構(gòu)建微服務(wù)架構(gòu)?

微服務(wù)的集成可以通過 Feign+Ribbon 以 RESTful 方式實(shí)現(xiàn)通信,也可以基于 RPC 方式(可以結(jié)合 Protocol Buffer)完成服務(wù)之間的通信,甚至可以通過發(fā)布事件與訂閱事件的機(jī)制。

事件機(jī)制可以使微服務(wù)之間更加松散耦合。這時(shí),我們可以引入 RabbitMQ 或 Kafka 來做到服務(wù)與服務(wù)之間的解耦。

事件機(jī)制是異步和非阻塞的,在某些業(yè)務(wù)場景下,它的性能會(huì)更加的好。Spring Cloud 也提供了相關(guān)的組件 Spring Cloud Stream 來支持這種事件機(jī)制。

對(duì)于微服務(wù)之間的協(xié)作,到底選擇 Feign 這種 REST 方式、事件機(jī)制或者 RPC 方式,取決于業(yè)務(wù)場景是否需要同步方式,還是異步方式;是高性能高并發(fā),還是普通方式;是要求徹底解耦,還是做到一般的松散耦合。

我們需要針對(duì)實(shí)際情況作出實(shí)際的判斷,作出正確的選擇。沒有誰壞誰好之分,而是看誰更加的適合。

作者:張逸

簡介:架構(gòu)編碼實(shí)踐者,IT 文藝工作者,大數(shù)據(jù)平臺(tái)架構(gòu)師,兼愛 OO 與 FP,熱衷于編程語言學(xué)習(xí)與技藝提升,致力于將主流領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)與函數(shù)式編程、響應(yīng)式編程以及微服務(wù)架構(gòu)完美結(jié)合。他的個(gè)人微信公眾號(hào)為「逸言」,個(gè)人博客:http://zhangyi.xyz。

網(wǎng)頁題目:如何使用SpringCloud構(gòu)建微服務(wù)架構(gòu)?-創(chuàng)新互聯(lián)
新聞來源:http://jinyejixie.com/article14/jgide.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司響應(yīng)式網(wǎng)站、網(wǎng)站營銷、域名注冊(cè)、品牌網(wǎng)站設(shè)計(jì)、Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)
颍上县| 湘乡市| 塔河县| 峡江县| 博兴县| 浏阳市| 格尔木市| 阳东县| 龙口市| 江川县| 平安县| 博湖县| 奉化市| 漳州市| 马龙县| 分宜县| 阿勒泰市| 禹州市| 进贤县| 分宜县| 巨鹿县| 镇远县| 东平县| 西乌| 镇远县| 泊头市| 霍山县| 古丈县| 恩平市| 镇原县| 镇赉县| 广元市| 峨眉山市| 筠连县| 莱阳市| 井研县| 建水县| 汕尾市| 双牌县| 襄垣县| 阿坝县|