说明:SpringCloud系列笔者自学系列,学习来源是周立的博客 http://www.itmuch.com/ 。而此处转载其博客只是为了方便自己以后的学习。
本篇来源 http://www.itmuch.com/spring-cloud/finchley-7/
经过前文讲述,我们已经实现了服务发现。本节来解决 跟我学Spring Cloud(Finchley版)-02-构建分布式应用 提到的如下问题:
负载均衡如何考虑?难道得在电影微服务和用户微服务之间加个NGINX做负载均衡吗?听起来是可行的,但如果有10000+服务(这并不夸张,我司的微服务数目是这个数字乘以N,N >= m,哈哈哈)那这个NGINX的配置得有多复杂……
一般来说,提到负载均衡,大家一般很容易想到浏览器 -> NGINX -> 反向代理多个Tomcat这样的架构图——业界管这种负载均衡模式叫“服务器端负载均衡”,因为此种模式下,负载均衡算法是NGINX提供的,而NGINX部署在服务器端。
本节所讲的Ribbon则是一个客户端侧负载均衡组件——通俗地说,就是集成在客户端(服务消费者一侧),并提供负载均衡算法的一个组件。
Ribbon简介
Ribbon是Netflix发布的负载均衡器,它可以帮我们控制HTTP和TCP客户端的行为。只需为Ribbon配置服务提供者地址列表,Ribbon就可基于负载均衡算法计算出要请求的目标服务地址。
Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机、响应时间加权等——当然,为Ribbon自定义负载均衡算法也非常容易,只需实现IRule
接口即可。
TIPS
Ribbon的GitHub:https://github.com/Netflix/ribbon
引入Ribbon
在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,选择其中一个服务提供者实例。下图展示了Ribbon与Eureka配合使用时的大致架构。
Ribbon入门
代码示例
复制项目
microservice-consumer-movie
,将ArtifactId修改为microservice-consumer-movie-ribbon
。加依赖:由于
spring-cloud-starter-netflix-eureka-client
已经包含spring-cloud-starter-netfilx-ribbon
,故而无需额外添加依赖。写代码:
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
如代码所示,只需在
RestTemplate
上添加LoadBalanced
注解,即可让RestTemplate整合Ribbon!调用:
@GetMapping("/users/{id}") public User findById(@PathVariable Long id) { // 这里用到了RestTemplate的占位符能力 User user = this.restTemplate.getForObject( "http://microservice-provider-user/users/{id}", User.class, id ); // ...电影微服务的业务... return user; }
由代码可知,我们将请求的目标服务改成了
http://microservice-provider-user/users/{id}
,也就是http://{目标服务名称}/{目标服务端点}
的形式,Ribbon会自动在实际调用时,将目标服务名替换为该服务的IP和端口。
测试
- 依次启动
microservice-discovery-eureka
、microservice-provider-user
两个实例、microservice-consumer-movie-ribbon
- 访问
http://localhost:8010/movies/users/1
多次,会发现两个user服务实例都会打印日志。
WARNING
事实上,这里的目标服务名称,在Ribbon里叫虚拟主机名
,主机名是不能包含_
等特殊字符的——这意味着,一般不建议配置spring.application.name = xxx_xxx
,如果你的应用名称一定(谁这么变态??)带有下划线这种字符,那么请额外配置eureka.instance.virtual-host-name = 一个合法的主机名
,否则Ribbon将会提示虚拟主机名不合法的异常(在早期的版本则是报空指针)!这点请大家务必注意。