三.Ribbon负载均衡
搭建步骤:
1.用户服务的集群
2.订单服务集成Ribbon
2.1.导入Ribbon的依赖
2.2.在RestTemplate的Bean定义方法上加上:@LoadBalanced注解
2.3.把订单的Controller向用户发起调用的restTemplate的url使用服务名调用,
如:"http://user-server/user/"+id;
3.负载均衡算法:主配置类配置负载均衡算法类的Bean即可
1.基本概念
1.1.为什么要Ribbon
- 我们知道,为了防止应用出现单节点故障问题,同时为了提高应用的作业能力,我们需要对应用做集群 ,如果我们对user-server做了集群,那么这个时候回衍生出一些问题:现在有两个user-server意味着有两个通信地址,我的order-server在向user-server发起调用的时候该访问哪个?如何访问?这个时候就需要有一个组件帮我们做请求的分发,即:负载均衡器,而Ribbon就是一个客户端负载均衡器。
1.2.什么是Ribbon
- Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端负载均衡算法。Ribbon客户端组件提供一系列完善的配置项,如,连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
1.3.Ribbon的工作机制
- 如下图,我们将user-server增加到2个节点(两个user-server的服务名要一样,ip和端口不一样),在注册中心的服务通信地址清单中user-server这个服务下面会挂载两个通信地址, 而订单服务会定时把服务通信地址清单拉取到本地进行缓存, 那么当order-server在向用户服务发起调用时,需要指定服务名为 user-server;那么这个时候,ribbon会根据user-server这个服务名找到两个用户服务的通信地址 , 然后ribbon会按照负载均衡算法(默认轮询)选择其中的某一个通信地址,发起http请求实现服务的调用。
2.提供者user-server集群
2.1.服务集群方案
- 使用SpringBoot多环境配置方式集群,一个配置文件配置多个用户服务环境,需要注意的是集群中的多个服务名(spring.application.name)应该一样,我们把相同的东西提取到最上面,不同的东西配置在各自的环境中。
2.2.用户服务集群配置
修改 application.yml 如下:
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://peer1:1010/eureka/,http://peer2:1011/eureka/,http://peer3:1012/eureka/
#使用ip地址进行注册
instance:
prefer-ip-address: true
spring:
application:
name: user-server #服务名都叫user-server
profiles:
active: user-server1
---
server:
port: 1020
eureka:
instance:
instance-id: user-server:1020
spring:
profiles: user-server1
---
server:
port: 1021
eureka:
instance:
instance-id: user-server:1021
spring:
profiles: user-server2
3.消费者Order-server集成Ribbon
官方文档:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi_spring-cloud-ribbon.html#netflix-ribbon-starter
修改springcloud-eureka-order-server-1030服务
3.1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-symltarter-netflix-ribbon</artifactId>
</dependency>
3.2.修改RestTemplate的Bean的定义
@LoadBalanced :ribbon的负载均衡标签,赋予RestTemplate有负债均衡的能力
/**
* 订单的启动类
*/
@SpringBootApplication
@EnableEurekaClient
public class OrderServerApplication1030
{
//配置一个RestTemplate ,Spring封装的一个机遇Restful风格的http客户端 工具
//@LoadBalanced :让RestTemplate有负载均衡的功能
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderServerApplicationConfig.class,args);
}
3.3.修改Controller调用方式
//订单服务
@RestController
public class OrderController {
//需要配置成Bean
@Autowired
private RestTemplate restTemplate;
//浏览器调用该方法
@RequestMapping(value = "/order/{id}",method = RequestMethod.GET)
public User getUserId(@PathVariable("id")Long id){
//发送http请求调用 user的服务,获取user对象 : RestTemplate
//user的ip,user的端口,user的Controller路径
String url = "http://user-server/user/" + id;
return restTemplate.getForObject(url,User.class);
}
}
3.4.配置负载均衡算法
Ribbon默认使用的轮询策略
- 把负载均衡算法类配置成Bean即可
//订单服务
@RestController
public class OrderController {
//需要配置成Bean
@Autowired
private RestTemplate restTemplate;
//负载均衡策略
@Bean
public RandomRule randomRule(){
return new RandomRule();
}
//浏览器调用该方法
@RequestMapping(value = "/order/{id}",method = RequestMethod.GET)
public User getUserId(@PathVariable("id")Long id){
//发送http请求调用 user的服务,获取user对象 : RestTemplate
//user的ip,user的端口,user的Controller路径
//String url = "http://localhost:1020/user/"+id; 单个用户服务的时候
String url = "http://user-server/user/" + id;
return restTemplate.getForObject(url,User.class);
}
}
3.5.Ribbon源码跟踪
1.@LoadBalanced 开启负载均衡
2.RibbonLoadBalancerClient.execute : 根据服务名选择一个服务, 发起调用
2.1.loadBalancer.chooseServer选择服务 : BaseLoadBalancer.chooseServer选择服务
2.2.IRule.choose : RandomRule.choose :按照具体的算法选择一个服务返回
3.向服务发起Http调用