51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

ribbon的服务调用和负载均衡

# (一)ribbon概述 {#一-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>

# (二)ribbon服务调用 {#二-ribbon服务调用}

服务调用:eureka内部继承了ribbon

1.在创建RestTemplate时,声明@LoadBalanced

2.使用restTemplate调用远程微服务,用服务的名称代替ip地址

还是回到之前的项目,这个项目可以看SpringCloud专题的前两篇博客,修改admin微服务中的启动类,在restTemplate中加上LoadBalanced注解:

@SpringBootApplication@EntityScan("com.sdxb.admin.entity")@EnableEurekaClientpublic class AdminApplication {
    //增加ribbon注解
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class,args);
    }}

在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;
    }}

注意一个可能发生的小错误,服务名称我们是在application.properties中定义的,服务名称不能出现下划线,否则会显示找不到该url

# (三)ribbon负载均衡 {#三-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;
    }}

通过@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

# (三)ribbon重试机制 {#三-ribbon重试机制}

ribbon属于客户端负载均衡,即客户端会选择要访问哪个微服务,如果这个时候微服务断掉了,就无法返回数据。因此需要引入重试机制。 重试机制的引入有两个步骤:

# 1.导入依赖: {#_1-导入依赖}

在客户端的pom.xml导入依赖

<!--引入重试依赖--><dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId></dependency>

# 2.填写相关配置 {#_2-填写相关配置}

配置的解释全部放在注解中了

#重试机制#ribbon连接超时时间userservice.ribbon.ConnectTimeout=250#ribbon读取数据超时时间userservice.ribbon.ReadTimeout=1000#是否对所有操作都重试userservice.ribbon.OkToRetryOnAllOperations=true#切换实例的重试次数userservice.ribbon.MaxAutoRetriesNextServer=1#对当前实例的重拾次数userservice.ribbon.MaxAutoRetries=1

赞(4)
未经允许不得转载:工具盒子 » ribbon的服务调用和负载均衡