SpringCloud - 服务注册与发现组件Eureka的使用详解4(服务发现与消费、负载均衡)
作者:hangge | 2020-07-03 08:10
在之前的文章中我演示了如何搭建服务注册中心和服务提供者,本文接着演示如何构建一个服务消费者,它主要完成两个目标:发现服务以及消费服务。其中发现服务的任务由 Eureka 的客户端完成,而服务消费的任务由 Ribbon 完成。
(3)启动后通过 Eureka 信息面板中可以看到名为 HELLO-SERVICE 的服务中出现了两个实例单元,分别是通过命令行启动的 8081 端口和 8082 端口的服务。
(2)接着编辑项目的 application.properites 文件,添加如下配置为服务命名,并指定服务注册中心的地址:
(3)主类上添加 @EnableDiscoveryClient 注解,让该应用注册为 Eureka 客户端应用,以获得服务发现的能力。同时,在该主类中创建 RestTemplate 的 Spring Bean 实例,并通过 @LoadBalanced 注解开启客户端负载均衡。
(4)创建一个 ConsumerController 并实现 /hello-consumer 接口。在该接口中,通过前面定义的 RestTemplate 来实现对 HELLO-SERVICE 服务提供的 /hello 接口进行调用:
(2)获取服务是服务消费者的基础,确保 eureka.client.fetch-registry 参数为 true(默认就是 true)
Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡器,它可以在通过客户端中配置的 ribbonServerList 服务端列表去轮询访问以达到均衡负载的作用。当 Ribbon 与 Eureka 联合使用时,Ribbon 的服务实例清单 RibbonServerList 会被 DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务端列表。同时它也会用 NIWSDiscoveryPing
来取代 IPing,它将职责委托给 Eureka 来确定服务端是否已经启动。
四、服务发现与消费
1,准备工作
(1)启动之前实现的服务注册中心 eureka-server,具体实现可以参考之前的文章:
(2)通过 java -jar 命令行的方式启动两个不同端口的 hello-service 服务:
hello-service 服务的实现可以参考之前写的文章:SpringBoot - 服务注册与发现组件Eureka的使用详解2(创建并注册服务提供者)
java -jar hello-service-0.0.1-SNAPSHOT.jar --server.port=8081 java -jar hello-service-0.0.1-SNAPSHOT.jar --server.port=8082
(3)启动后通过 Eureka 信息面板中可以看到名为 HELLO-SERVICE 的服务中出现了两个实例单元,分别是通过命令行启动的 8081 端口和 8082 端口的服务。
2,创建服务消费者
(1)创建一个 Spring Boot 工程(ribbon-consumer)来实现服务消费者,首先在 pom 文件中引入相关依赖:
注意:相较于前面的服务提供者 hello-service,这里新增了 Ribbon 模块的依赖 spring-cloud-starter-netflix-ribbon。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
(2)接着编辑项目的 application.properites 文件,添加如下配置为服务命名,并指定服务注册中心的地址:
#设置端口,防止冲突
server.port=9000
#为服务命名
spring.application.name=ribbon-consumer
#指定服务注册中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
(3)主类上添加 @EnableDiscoveryClient 注解,让该应用注册为 Eureka 客户端应用,以获得服务发现的能力。同时,在该主类中创建 RestTemplate 的 Spring Bean 实例,并通过 @LoadBalanced 注解开启客户端负载均衡。
- 之后我们就可以使用被 @LoadBalanced 注释修饰过的 RestTemplate 来实现面向服务的接口调用。
- 而 Spring Cloud Ribbon 中实现客户端负载均衡的原理简单来说:就是通过 LoadBalancerInterceptor 拦截器对 RestTemplate 的请求进行拦截,并利用 Spring Cloud 的负载均衡器 LoadBalancerClient 将一服务名为 host 的 URI 转换成具体的服务实例地址的过程。
@SpringBootApplication @EnableDiscoveryClient public class RibbonConsumerApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonConsumerApplication.class, args); } }
(4)创建一个 ConsumerController 并实现 /hello-consumer 接口。在该接口中,通过前面定义的 RestTemplate 来实现对 HELLO-SERVICE 服务提供的 /hello 接口进行调用:
注意:可以看到这里访问的地址是服务名 HELLO-SERVICE,而不是一个具体的地址。
@RestController public class ConsumerController { @Autowired RestTemplate restTemplate; @GetMapping("/hello-consumer") public String helloConsumer() { // 通过服务名调用服务提供者的接口 return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody(); } }
3,运行测试
(1)启动 ribbon-consumer 应用后,我们可以在 Eureka 信息面板中看到当前除了 HELLO-SERVICE 外,还多了我们实现的 RIBBON-CONSUMER。
(2)而通过向 http://localhost:9000/hello-consumer 发起请求是,可以在 ribbon-consumer 应用的控制台中看到如下信息。
Ribbon 输出了当前客户端维护的 HELLO-SERVICE 的服务列表情况。其中包含了各个实例的位置,Ribbon 就是按照此信息进行轮训访问,以实现基于客户端的负载均衡。
除此之外还输出了一些其他非常有用的信息,如对各个实例的请求总数量、第一次连接信息、上一次连接信息、总的请求失败数量等。
除此之外还输出了一些其他非常有用的信息,如对各个实例的请求总数量、第一次连接信息、上一次连接信息、总的请求失败数量等。
(3)如果尝试多发起几次请求,并观察两个服务提供者 HELLO-SERVICE 的控制台,可以看到这两个控制台会交替打印如下日志(这个是之前在 HelloController 中对服务信息的输出),说明当前 ribbon-consumer 对 HELLO-SERVICE 的调用是负载均衡的。
附:其他一些常用配置
1,获取服务
(1)当我们启动服务消费者的时候,它会发送一个 REST 请求给服务注册中心,来获取上面注册的服务请求清单。(2)获取服务是服务消费者的基础,确保 eureka.client.fetch-registry 参数为 true(默认就是 true)
#获取服务
eureka.client.fetch-registry=true
2,服务清单更新时间
为了性能考虑,Eureka Server 会维护一份只读的服务清单来返回给客户端,同时缓存清单会每隔 30 秒更新一次。我们可以通过如下参数修改缓存清单的更新时间:#修改缓存清单的更新时间。默认为30秒
eureka.client.registry-fetch-interval-seconds=30
全部评论(0)