GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

微服务 Spring Cloud Alibaba 之我见

2020 年 6 月 12 日

微服务Spring Cloud Alibaba之我见

如果你正在寻找一个 Spring Cloud Netflix 的替代方案 ,建议可以看下这篇和 Spring Cloud Alibaba 相关的文章。


前段时间,Spring Cloud 在其官方博客宣布:阿里巴巴开源 Spring Cloud Alibaba,发布了首个预览版本 0.2.0,并已和 Spring Boot 2.0 兼容,该项目支持基于阿里巴巴的开源组件和阿里云云产品,构建微服务体系。

这个项目看起来非常有趣,并且目前已成为 SpringCloud 孵化器仓库中最流行的项目之一。



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 网关之后。



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 字段中。



好消息是,它在修改了 Nacos 之后会动态刷新应用程序配置。在应用程序中,您唯一要做的就是注释应该用 @RefreshScope 或 @ConfigurationProperties 刷新的 bean。


现在,让我们考虑以下情况。我们将稍微修改一下配置,以添加一些带有测试数据的属性,如下所示。



这是我们存储库 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,您应该会看到具有修改值的雇员的完整列表。



对于我们另外两个微服务,部门服务和组织服务,应该创建相同的配置属性。假设您已经完成了,那么您应该在 Nacos 上具有以下配置条目。



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 实例的数量。



如果希望测试服务间通信,可以调用以下方法,这些方法使用 OpenFeign 客户端调用其他微服务公开的端点:GET /organization/{organizationId}/with-employees from department-service, and GET /{id}/with-departments, GET /{id}/with-departments-and-employees, GET /{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 站点上找到其他一些示例。


作者介绍


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


原文链接


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


2020 年 6 月 12 日 17:521320

评论

发布
暂无评论
发现更多内容

GopherChina 2021 定了,干货满满的来了

GoCN技术社区

go GopherChina

2021金三银四面试必备?体系化带你学习:分布式进阶技术手册

比伯

Java 架构 程序人生 编程语言 技术宅

币安智能链智能合约Dapp系统开发技术

薇電13242772558

智能合约

MySQL数据库函数、DCL详解(及备份恢复操作)

若尘

MySQL 数据库 备份 DCL

头一次见,阿里大牛把计算机网络协议讲得这么有趣,已火爆Github

周老师

Java 编程 程序员 架构 面试

1000道最新整理的Java 技术考题及解答,抢先直通TMDBATJW拿高薪

钟奕礼

Java 编程 程序员 架构 面试

为用户重命名

在即

四月日更

安卓rxjava使用,现在做Android开发有前途吗?附面试题答案

欢喜学安卓

android 程序员 面试 移动开发

上次挂在了京东(Java岗)二面不服气,这次终于拿下offer,皇天不负有心人了也是!

钟奕礼

Java 编程 程序员 架构 面试

智慧党建管理系统开发方案,组织部干部人事管理平台建设

WX13823153201

anyRTC 实时音视频打造安全合规壁垒

anyRTC开发者

网络安全 WebRTC RTC

如何使用iMazing将iPhone的数据迁移到iPad

懒得勤快

iphone ipad 苹果 数据迁移 数据备份

世界级运维专家巨作:793页Linux实战手记,GitHub点击量已超千万

周老师

Java 编程 程序员 架构 面试

复习一周,字节跳动三场技术面+HR面,不小心拿了offer

Crud的程序员

Java 编程 架构 Java工程师

源中瑞区块链Baas平台--助力区块链应用落地

13530558032

Java 面试题目最全集合1000+ 大放送,能答对70%就去BATJTMD

钟奕礼

Java 编程 程序员 架构 面试

牛客网转发超50万次的Java面试指南!已成功帮我在金三斩获6个Offer

神奇小汤圆

Java 编程 程序员 架构 面试

区块链“数据上链”管理系统

电微13828808271

什么是自然语言处理(NLP)?

澳鹏Appen

人工智能 自然语言处理 聊天机器人 nlp 自然语言

java中三种内存溢出错误的处理方法

Sakura

四月日更

工业机器视觉系统相机如何选型?

不脱发的程序猿

工业物联网 四月日更 LabVIEW 工业视觉 工业机器视觉

「 最具技术影响力企业号 TOP10 」—— InfoQ 写作平台【 1 周年盛典 】

InfoQ写作平台官方

1 周年盛典

区块链商品溯源平台--全流程捍卫食品安全

13530558032

区块链结合农业产业,平台全程溯源

电微13828808271

架构师训练营 模块2作业

eoeoeo

架构实战营

项目管理之相关方管理

Geek_XOXO

项目管理 复盘 相关方管理

量化倍投系统开发,量化马丁策略交易平台搭建app

WX13823153201

量化倍投系统开发

app启动速度优化,分享一点面试小经验,最全的BAT大厂面试题整理

欢喜学安卓

android 程序员 面试 移动开发

HECO火币链智能合约Dapp系统开发方案

薇電13O25249123

智能合约 dapp

Kotlin @inline内联函数

季浩田 🍙

kotlin inline

全网下载量过亿!12万字阿里内部Java面试手册有多强?

Java架构追梦

Java 架构 面试 成长笔记 阿里巴巴内部资料

DNSPod与开源应用专场

DNSPod与开源应用专场

微服务Spring Cloud Alibaba之我见-InfoQ