ribbon的服务调用和负载均衡
作者:鱼仔
博客首页: https://codeease.top
公众号:Java鱼仔
# (一)ribbon概述
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。
ribbon的主要作用是服务调用和负载均衡
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2
3
4
# (二)ribbon服务调用
服务调用:eureka内部继承了ribbon
1.在创建RestTemplate时,声明@LoadBalanced
2.使用restTemplate调用远程微服务,用服务的名称代替ip地址
还是回到之前的项目,这个项目可以看SpringCloud专题的前两篇博客,修改admin微服务中的启动类,在restTemplate中加上LoadBalanced注解:
@SpringBootApplication
@EntityScan("com.sdxb.admin.entity")
@EnableEurekaClient
public class AdminApplication {
//增加ribbon注解
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class,args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在adminController中使用服务名称代替ip地址
@RestController
@RequestMapping("/admin")
public class adminController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public User getuser(@PathVariable int id){
//使用服务名称代替IP地址
User user= restTemplate.getForObject("http://userservice/user/"+id,User.class);
return user;
}
}
2
3
4
5
6
7
8
9
10
11
12
注意一个可能发生的小错误,服务名称我们是在application.properties中定义的,服务名称不能出现下划线,否则会显示找不到该url
# (三)ribbon负载均衡
ribbon最主要的功能不是远程调用,而是负载均衡,所谓负载均衡就是将请求分摊到各个微服务中,缓解服务器的压力。举个例子有相同的三个微服务ABC,都能实现同样的功能,此时一个请求发过来的时候,就需要客户端或服务器通过一定算法决定该给哪个微服务。
常见的服务器端负载均衡:nginx
常见的客户端负载均衡:ribbon
服务器端负载均衡是指服务器接收到请求后选择发给哪个服务,客户端负载均衡是指客户端决定了发给哪个服务从而实现负载均衡。
负载均衡实战:
首先对原来的userservice做个小小的修改,让它的数据中带有该微服务的ip地址和端口号:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
@Value("${server.port}")
private String port;//使用注解获取端口号
@Value("${spring.cloud.client.ip-address}")
private String ip;//使用注解获取ip地址
@GetMapping("/{id}")
public User user(@PathVariable("id") int id){
User user = userMapper.selectbyid(id);
user.setUsername(ip+":"+port);
return user;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
通过@Value注解获取到端口号和ip地址,写到user的name中 启动eureka注册中心和UserApplication,将user微服务注册到eureka注册中心中,在Run DashBoard中copy一份UserApplication,命名为UserApplication2
修改UserService的端口号为9010,启动UserApplication2
在浏览器中输入http://localhost:9000/,可以看到两个端口都注册到eureka注册中心了
启动adminApplication,在浏览器中输入http://localhost:9002/admin/1
通过刷新浏览器可以看到负载均衡的效果。
负载均衡算法:
ribbon提供了许多负载均衡算法:
com.netflix.loadbalancer.RoundRobinRule 轮询的方式负载均衡(默认)
com.netflix.loadbalancer.RandomRule 随机
com.netflix.loadbalancer.RetryRule 重试
com.netflix.loadbalancer.WeightedResponseTimeRule 权重策略
com.netflix.loadbalancer.BestAvailableRule 最佳策略
com.netflix.loadbalancer.AvailabilityFilteringRule 过滤策略
用得比较多的轮询和权重策略,当所用的服务器配置有高有低时,推荐权重策略,它会计算每个服务器的权重。
修改负载均衡算法的方式也很简单,在你想修改负载均衡的客户端微服务的配置文件application.properties下,增加下面的语句:
微服务名称.ribbon.NFLoadBalancerRuleClassName=所采用的方式的全限定类名(上面红色字体),我将策略修改为随机,重启服务后刷新浏览器,发现所调用的服务不再是轮询了。
#修改ribbon负载均衡策略
userservice.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
2
# (三)ribbon重试机制
ribbon属于客户端负载均衡,即客户端会选择要访问哪个微服务,如果这个时候微服务断掉了,就无法返回数据。因此需要引入重试机制。 重试机制的引入有两个步骤:
# 1.导入依赖:
在客户端的pom.xml导入依赖
<!--引入重试依赖-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
2
3
4
5
# 2.填写相关配置
配置的解释全部放在注解中了
#重试机制
#ribbon连接超时时间
userservice.ribbon.ConnectTimeout=250
#ribbon读取数据超时时间
userservice.ribbon.ReadTimeout=1000
#是否对所有操作都重试
userservice.ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
userservice.ribbon.MaxAutoRetriesNextServer=1
#对当前实例的重拾次数
userservice.ribbon.MaxAutoRetries=1
2
3
4
5
6
7
8
9
10
11