1. 回顾web
在前面,已经实现了微服务的注册与发现。启动各个微服务时,Eureka Client会把本身的网络信息注册到Eureka Server上。算法
可是,在生成环境中,各个微服务都会部署多个实例,所以还行继续进行优化。spring
2. Ribbon简介网络
Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,架构
自动地帮助服务消费者去请求。Ribbon默认为咱们提供了不少的负载均衡算法,例如轮询、随机等。咱们也可为Ribbon实现自定义的负载均衡算法。app
在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。负载均衡
3. 为服务消费者整合Ribbonide
> 复制项目 microservice-consumer-movice,修改ArtifactId为 microservice-consumer-movie-ribbon微服务
> 为项目microservice-consumer-movie添加Ribbon的依赖。可是前文已经为该服务添加spring-cloud-starter-netflix-eureka-client依赖,优化
该依赖已经包含了 spring-cloud-starter-netflix-ribbon 依赖,因此无需再次引入。
> 在启动类中,为RestTemplate添加@LoadBalanced注解。
package com.itmuch.cloud.microserviceconsumermovie; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient public class MicroserviceConsumerMovieApplication { public static void main(String[] args) { SpringApplication.run(MicroserviceConsumerMovieApplication.class, args); } @Bean @LoadBalanced // 实现负载均衡
public RestTemplate restTemplate() { return new RestTemplate(); } }
> 修改MovieController类,便于发现是否实现负载均衡
package com.itmuch.cloud.microserviceconsumermovie.controller; import com.itmuch.cloud.microserviceconsumermovie.pojo.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class MovieController { private static final Logger LOGGER = LoggerFactory.getLogger(MovieController.class); @Autowired private RestTemplate restTemplate; @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/user/{id}") public User findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class); } @GetMapping("/log-instance") public void logUserInstance() { ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user"); // 打印当前选择的是哪一个节点
MovieController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort()); } }
> 启动 microservice-discovery-eureka
> 启动两个以上的 microservice-provider-user 实例(启动前检查application.yml,spring.jpa.hibernate.ddl-auto值为update,不然不能自动建立表结构;
检查eureka.client.service-url.defaultZone的值是否为注册中心的url)
> 启动 microservice-consumer-movie-ribbon
> 屡次访问 http://localhost:8010/user/1
而且,在多个 microservice-provider-user 实例中都会打印以下日志:
代表:Ribbon成功的将请求负载到不一样的实例上了
> 屡次访问 http://localhost:8010/log-instance ,在 microservice-consumer-movie 项目的日志中可发现以下日志:
代表:Ribbon成功的将请求负载到不一样的实例上了
4. 总结
本文已经实现了用Ribbon实现客户端的负载均衡。
下次将讲解自定义Ribbon配置,敬请期待~~~
5. 参考
周立 --- 《Spring Cloud与Docker微服务架构与实战》