赞
踩
Spring Cloud Alibaba 提供的 Spring Cloud Alibaba Nacos Discovery 组件,基于 Spring Cloud 的编程模型,接入 Nacos 作为注册中心,实现服务的注册与发现。
服务发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于服务的动态扩缩容。
Nacos Discovery 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。
除此之外,Nacos Discovery 也将服务实例自身的一些元数据信息-例如 host,port, 健康检查URL,主页等内容注册到 Nacos。
在使用注册中心时,一共有三种角色:服务提供者(Service Provider)、服务消费者(Service Consumer)、注册中心(Registry)。
在一些文章中,服务提供者被称为 Server,服务消费者被称为 Client。
三个角色交互如下图所示:
① Provider:
② Consumer:
③ Registry:
当然,不同的注册中心可能在实现原理上会略有差异。例如说,Eureka 注册中心,并不提供通知功能,而是 Eureka Client 自己定期轮询,实现本地缓存的更新。
另外,Provider 和 Consumer 是角色上的定义,一个服务同时即可以是 Provider 也可以作为 Consumer。例如说,优惠劵服务可以给订单服务提供接口,同时又调用用户服务提供的接口。
本小节,我们来搭建一个 Nacos Discovery 组件的快速入门示例。步骤如下:
demo-provider
,注册服务到 Nacos 中。demo-consumer
,从 Nacos 获取到 demo-provider
服务的实例列表,选择其中一个示例,进行 HTTP 远程调用。创建 labx-01-sca-nacos-discovery-demo01-provider
项目,作为服务提供者 demo-provider
。最终项目代码如下图所示:
在 pom.xml
文件中,主要引入 Spring Cloud Nacos Discovery 相关依赖。代码如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>labx-01</artifactId> <groupId>cn.iocoder.springboot.labs</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>labx-01-sca-nacos-discovery-demo01-provider</artifactId> <properties> <spring.boot.version>2.2.4.RELEASE</spring.boot.version> <spring.cloud.version>Hoxton.SR1</spring.cloud.version> <spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version> </properties> <!-- 引入 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。 在 https://dwz.cn/mcLIfNKt 文章中,Spring Cloud Alibaba 开发团队推荐了三者的依赖关系 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入 SpringMVC 相关依赖,并实现对其的自动配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 引入 Spring Cloud Alibaba Nacos Discovery 相关依赖,将 Nacos 作为注册中心,并实现对其的自动配置 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> </project> |
在
<dependencyManagement />
中,我们引入了 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。在《Spring Cloud 官方文档 —— 版本说明》文档中,推荐了三者的依赖关系。如下表格:
Spring Cloud Version | Spring Cloud Alibaba Version | Spring Boot Version |
---|---|---|
Spring Cloud Greenwich | 2.1.1.RELEASE | 2.1.X.RELEASE |
Spring Cloud Finchley | 2.0.1.RELEASE | 2.0.X.RELEASE |
Spring Cloud Edgware | 1.5.1.RELEASE | 1.5.X.RELEASE |
2.2.0.RELEASE
。1.1.4
。引入 spring-cloud-starter-alibaba-nacos-discovery
依赖,将 Nacos 作为注册中心,并实现对它的自动配置。
创建 application.yaml
配置文件,添加 Nacos Discovery 配置项。配置如下:
spring: application: name: demo-provider # Spring 应用名 cloud: nacos: # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 discovery: server-addr: 127.0.0.1:8848 # Nacos 服务器地址 service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 server: port: 18080 # 服务器端口。默认为 8080 |
重点看 spring.cloud.nacos.discovery
配置项,它是 Nacos Discovery 配置项的前缀,对应 NacosDiscoveryProperties 配置项。
创建 DemoProviderApplication 类,创建应用启动类,并提供 HTTP 接口。代码如下:
@SpringBootApplication @EnableDiscoveryClient public class DemoProviderApplication { public static void main(String[] args) { SpringApplication.run(DemoProviderApplication.class, args); } @RestController static class TestController { @GetMapping("/echo") public String echo(String name) { return "provider:" + name; } } } |
① @SpringBootApplication
注解,被添加在类上,声明这是一个 Spring Boot 应用。Spring Cloud 是构建在 Spring Boot 之上的,所以需要添加。
② @EnableDiscoveryClient
注解,开启 Spring Cloud 的注册发现功能。不过从 Spring Cloud Edgware 版本开始,实际上已经不需要添加 @EnableDiscoveryClient
注解,只需要引入 Spring Cloud 注册发现组件,就会自动开启注册发现的功能。例如说,我们这里已经引入了 spring-cloud-starter-alibaba-nacos-discovery
依赖,就不用再添加 @EnableDiscoveryClient
注解了。
拓展小知识:在 Spring Cloud Common 项目中,定义了 DiscoveryClient 接口,作为通用的发现客户端,提供读取服务和读取服务列表的 API 方法。而想要集成到 Spring Cloud 体系的注册中心的组件,需要提供对应的 DiscoveryClient 实现类。
例如说,Spring Cloud Alibaba Nacos Discovery 提供了 NacosDiscoveryClient 实现,Spring Cloud Netflix Eureka 提供了 EurekaDiscoveryClient 实现。
如此,所有需要使用到的地方,只需要获取到 DiscoveryClient 客户端,而无需关注具体实现,保证其通用性。
③ TestController 类,提供了 /echo
接口,返回 provider:${name}
结果。
① 通过 DemoProviderApplication 启动服务提供者,IDEA 控制台输出日志如:
// ... 省略其它日志 2020-02-08 15:25:57.406 INFO 27805 --- [ main] c.a.c.n.registry.NacosServiceRegistry : nacos registry, DEFAULT_GROUP demo-provider 10.171.1.115:18080 register finished |
demo-provider
注册到 Nacos 上的日志。② 打开 Nacos 控制台,可以在服务列表看到服务 demo-provider
。如下图:
创建 labx-01-sca-nacos-discovery-demo01-consumer
项目,作为服务提供者 demo-consumer
。最终项目代码如下图所示:
整个项目的代码,和服务提供者是基本一致的
和「3.1.1 引入依赖」一样,只是修改 Maven <artifactId />
为 labx-01-sca-nacos-discovery-demo01-consumer
,见 pom.xml
文件。
创建 application.yaml
配置文件,添加相应配置项。配置如下:
spring: application: name: demo-consumer # Spring 应用名 cloud: nacos: # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 discovery: server-addr: 127.0.0.1:8848 # Nacos 服务器地址 server: port: 28080 # 服务器端口。默认为 8080 |
和「3.1.2 配置文件」基本一致,主要是将配置项目 spring.application.name
修改为 demo-consumer
。
创建 DemoConsumerApplication 类,创建应用启动类,并提供一个调用服务提供者的 HTTP 接口。代码如下:
@SpringBootApplication // @EnableDiscoveryClient public class DemoConsumerApplication { public static void main(String[] args) { SpringApplication.run(DemoConsumerApplication.class, args); } @Configuration public class RestTemplateConfiguration { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } @RestController static class TestController { @Autowired private DiscoveryClient discoveryClient; @Autowired private RestTemplate restTemplate; @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/hello") public String hello(String name) { // <1> 获得服务 `demo-provider` 的一个实例 ServiceInstance instance; if (true) { // 获取服务 `demo-provider` 对应的实例列表 List<ServiceInstance> instances = discoveryClient.getInstances("demo-provider"); // 选择第一个 instance = instances.size() > 0 ? instances.get(0) : null; } else { instance = loadBalancerClient.choose("demo-provider"); } // <2> 发起调用 if (instance == null) { throw new IllegalStateException("获取不到实例"); } String targetUrl = instance.getUri() + "/echo?name=" + name; String response = restTemplate.getForObject(targetUrl, String.class); // 返回结果 return "consumer:" + response; } } } |
① @EnableDiscoveryClient
注解,因为已经无需添加,所以我们进行了注释,原因在上面已经解释过。
② RestTemplateConfiguration 配置类,创建 RestTemplate Bean。RestTemplate 是 Spring 提供的 HTTP 调用模板工具类,可以方便我们稍后调用服务提供者的 HTTP API。
③ TestController 提供了 /hello
接口,用于调用服务提供者的 /demo
接口。代码略微有几行,我们来稍微解释下哈。
discoveryClient
属性,DiscoveryClient 对象,服务发现客户端,上文我们已经介绍过。这里我们注入的不是 Nacos Discovery 提供的 NacosDiscoveryClient,保证通用性。未来如果我们不使用 Nacos 作为注册中心,而是使用 Eureka 或则 Zookeeper 时,则无需改动这里的代码。
loadBalancerClient
属性,LoadBalancerClient 对象,负载均衡客户端。稍后我们会使用它,从 Nacos 获取的服务 demo-provider
的实例列表中,选择一个进行 HTTP 调用。
拓展小知识:在 Spring Cloud Common 项目中,定义了LoadBalancerClient 接口,作为通用的负载均衡客户端,提供从指定服务中选择一个实例、对指定服务发起请求等 API 方法。而想要集成到 Spring Cloud 体系的负载均衡的组件,需要提供对应的 LoadBalancerClient 实现类。
例如说,Spring Cloud Netflix Ribbon 提供了 RibbonLoadBalancerClient 实现。
如此,所有需要使用到的地方,只需要获取到 DiscoveryClient 客户端,而无需关注具体实现,保证其通用性。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/284333
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。