微服務Spring Cloud Alibaba之我見

技術瑣話發表於2018-12-20


作者:Piotr Mińkowski,“Mastering Spring Cloud”一書作者

原文連結:

https://dzone.com/articles/microservices-with-spring-cloud-alibaba


 

微服務Spring Cloud Alibaba之我見

如果你正在尋找一個Spring Cloud Netflix的替代方案,建議可以看下這篇和Spring Cloud Alibaba相關的文章。

前段時間,Spring Cloud在其官方部落格宣佈:阿里巴巴開源 Spring Cloud Alibaba,釋出了首個預覽版本0.2.0,並已和Spring Boot 2.0相容,該專案支援基於阿里巴巴的開源元件和阿里云云產品,構建微服務體系。

這個專案看起來非常有趣,並且目前已成為SpringCloud孵化器倉庫中最流行的專案之一。

微服務Spring Cloud Alibaba之我見


Spring Cloud還支援另一個流行的阿里巴巴開源元件——Sentinel,他負責流量控制、併發、斷路和負載保護。

我們的演示示例由三個微服務和API閘道器組成,非常類似於我之前寫過的一篇文章《基於SpringBoot 2.0、Eureka和Spring Cloud搭建微服務的快速指南》中所描述的體系結構。

唯一的區別在於,用於配置管理和服務發現的工具。微服務呼叫服務暴露的介面,而department-service呼叫employee-service暴露的介面,使用OpenFeign客戶端實現了服務間的通訊。整個系統的複雜性隱藏在使用NetflixZuul實現的API閘道器之後。

“SpringCloud Alibaba是否可以替代SpringCloud Netflix?”

答案是肯定的,但不是全部。Spring Cloud Alibaba仍然與Ribbon整合,Ribbon是基於服務發現的負載平衡。在這種情況下,Netflix Eureka很有可能被Nacos替換掉。

Nacos(DynamicNaming and Configuration Service)是一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺易於使用的平臺,按照這個定義,您可以使用Nacos用於:

  • 服務發現-可以註冊您的微服務,並通過DNS或HTTP介面發現其他微服務。它還為註冊服務提供實時健康檢查。

  • 分散式配置——Nacos提供的動態配置服務允許您在所有環境中以集中和動態的方式管理所有服務的配置。事實上,您也可以使用它來替換Spring Cloud Config Server。

  • 動態DNS——它支援加權路由,使得更容易實現中間層負載平衡、靈活的路由策略、流控制和簡單的DNS解析服務。

Spring Cloud還支援另一個流行的阿里巴巴開源元件——Sentinel,他負責流量控制、併發、斷路和負載保護。

我們的演示示例由三個微服務和API閘道器組成,非常類似於我之前寫過的一篇文章《基於SpringBoot 2.0、Eureka和Spring Cloud搭建微服務的快速指南》中所描述的體系結構。唯一的區別在於,用於配置管理和服務發現的工具。

微服務呼叫服務暴露的介面,而department-service呼叫employee-service暴露的介面,使用OpenFeign客戶端實現了服務間的通訊。整個系統的複雜性隱藏在使用NetflixZuul實現的API閘道器之後。

微服務Spring Cloud Alibaba之我見


1. 執行Nacos伺服器

您可以在Windows和Linux系統上執行Nacos。首先,您應該下載GitHub上提供的最新穩定版本。解壓縮之後,必須通過執行以下命令以單機模式執行它:

cmd nacos/bin/startup.cmd -m standalone

 預設情況下,Nacos從埠8848開始。它提供/nacos/v1下的HTTP API,以及地址http://localhost:8848/nacos下的管理web控制檯。如果檢視日誌,您會發現它只是一個使用SpringFramework編寫的應用程式。


 2. 依賴關係

正如我前面提到的,Spring Cloud Alibaba仍然處於孵化階段,因此它不包含在SpringCloud Release Train中。這就是為什麼我們需要在pom.xml的依賴關係管理部分中包括一個針對阿里巴巴的特殊BOM。我們還將使用Spring Cloud的最新穩定版本,即現在的Finchley.SR2。


<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Finchley.SR2</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>0.2.0.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies>

Spring Cloud Alibaba為當前支援的元件提供了三個啟動器。這些是使用Nacos進行服務發現的spring-cloud-starter-alibaba-nacos-discovery、用於分散式配置的spring-cloud-starter-alibaba-nacos-config以及用於限流降級的spring-cloud-starter-alibaba-sentinel。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos- discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos- config</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>

3. 使用Nacos啟用分散式配置

為了啟用Nacos的配置管理,我們只需要引入一個starter,即spring-cloud-starter-alibaba-nacos-config。它不提供Nacos伺服器的自動配置地址,因此我們需要為bootstrap.yml檔案中的應用程式顯式地設定它。

spring:application:name: employee-servicecloud:nacos:  config:    server-addr: localhost:8848

 我們的應用程式嘗試與Nacos連線,並獲取在檔案中提供的與屬性spring.application.name的值同名的配置。目前,Spring Cloud Alibaba只支援.properties檔案,因此我們需要在檔案employee-service.properties內建立配置。

Nacos提供了建立和管理配置屬性的優雅方式。我們可以使用網路管理控制檯來做到這一點。下面圖片中可見的欄位Data ID實際上是配置檔案的名稱。配置屬性列表應該放在Configuration Content欄位中。

微服務Spring Cloud Alibaba之我見

好訊息是,它在修改了Nacos之後會動態重新整理應用程式配置。在應用程式中,您唯一要做的就是註釋應該用@RefreshScope或@ConfigurationProperties重新整理的bean。

現在,讓我們考慮以下情況。我們將稍微修改一下配置,以新增一些帶有測試資料的屬性,如下所示。


微服務Spring Cloud Alibaba之我見

 


這是我們儲存庫bean的實現。它將帶有字首repository.employees的所有配置屬性注入到employees列表中。

@Repository@ConfigurationProperties(prefix = "repository")public class EmployeeRepository {private List < Employee > employees = new ArrayList < > ();public List < Employee > getEmployees() {return employees;}public void setEmployees(List < Employee > employees) {this.employees = employees;}public Employee add(Employee employee) {employee.setId((long)(employees.size() + 1));employees.add(employee);return employee;}public Employee findById(Long id) {Optional < Employee > employee = employees.stream().filter(a - > a.getId().equals(id)).findFirst();if (employee.isPresent())return employee.get();elsereturn null;}public List < Employee > findAll() {return employees;}public List < Employee > findByDepartment(Long departmentId) {return employees.stream().filter(a -> a.getDepartmentId().equals(departmentId)).collect(Collectors.toList());}public List < Employee > findByOrganization(Long organizationId) {return employees.stream().filter(a -> a.getOrganizationId().equals(organizationId)).collect(Collectors.toList());}}

現在,您可以更改一些屬性值,如下圖所示。然後,如果呼叫在埠8090(http://localhost:8090)上可用的employee-service,您應該會看到具有修改值的僱員的完整列表。

 

微服務Spring Cloud Alibaba之我見

對於我們另外兩個微服務,部門服務和組織服務,應該建立相同的配置屬性。假設您已經完成了,那麼您應該在Nacos上具有以下配置條目。

微服務Spring Cloud Alibaba之我見


4. 使用Nacos啟用服務發現

要使用Nacos實現服務發現,首先需要包括starterspring-cloud-starter-alibaba-nacos-discovery。配置伺服器也是如此;您還需要在bootstrap.yml檔案中設定Nacos伺服器的地址。

spring: application:   name: employee-service cloud: nacos:  discovery:    server-addr: localhost:8848

 最後一步是通過使用@EnableDiscoveryClient註釋主類來為應用程式啟用發現客戶端。

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

 如果您為所有的微服務提供相同的實現並執行它們,您將在Nacos Web控制檯中看到以下已註冊的應用程式列表。 

5.  服務間的通訊

微服務之間的通訊是使用標準Spring Cloud元件實現:RestTemplate或OpenFeign客戶端。

預設情況下,負載平衡由Ribbon客戶端實現。與Spring Cloud Netflix相比,唯一的區別之前的服務註冊中心使用的是 SpringCloud Netflix。下面是負責與employee service公開的端點GET/department/{departmentId} 通訊的 FeignClient 客戶端在部門服務中整合的實現。

@FeignClient(name = "employee-service")public interface EmployeeClient {@GetMapping("/department/{departmentId}")List < Employee > findByDepartment(@PathVariable("departmentId") Long departmentId);}

不要忘記為Spring Boot應用程式啟用Feign客戶端。

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


我們還應該執行多個employee-service例項,以便在客戶端測試負載均衡。在此之前,我們可以通過在Nacos上儲存的配置中將屬性server.port設定為0,來啟用埠號的動態生成。

現在,我們可以使用相同的配置設定執行單個服務的許多例項,而不必擔心單個微服務的埠號衝突。讓我們擴大employee-service例項的數量。


微服務Spring Cloud Alibaba之我見


如果希望測試服務間通訊,可以呼叫以下方法,這些方法使用OpenFeign客戶端呼叫其他微服務公開的端點:GET /organization/{organizationId}/with-employees from department-service, and GET /{id}/with-departmentsGET /{id}/with-departments-and-employeesGET /{id}/with-employees from organization-service.

6. 執行API閘道器

現在是執行體系結構中最後一個元件——API閘道器。它建在Spring Cloud Netflix Zuul之上,同樣使用Nacos作為發現和配置伺服器。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>

 在包括所需的依賴項之後,我們需要為應用程式啟用Zuul代理和發現客戶端。

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

以下是為我們的三個示例微服務定義的Zuul路由的配置:  

zuul:  routes:  department:    path: /department/**  serviceId: department-serviceemployee:  path: /employee/**  serviceId: employee-serviceorganization:  path: /organization/**  serviceId: organization-service

在執行閘道器之後,它為所有定義的微服務公開的API公開了Swagger2規範。假設您已經在埠8080上執行了它,那麼您可以在地址http://localhost:8080/swagger-ui.html下訪問它。由於這個原因,您可以從一個單獨的位置呼叫方法。

7. 結論

示例應用程式的原始碼可以在GitHub上通過阿里巴巴分支中的sample-spring-microservices-new獲得。

本文的主要目的是展示如何使用用於服務發現和配置管理的AlibabaNacos替換一些流行的SpringCloud元件。

SpringCloud Alibaba專案處於開發的早期階段,所以我們可能在不久的將來期待一些新的有趣的特性。您也可以在此處Spring Cloud Alibaba GitHub站點上找到其他一些示例。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562044/viewspace-2285943/,如需轉載,請註明出處,否則將追究法律責任。

相關文章