SpringCloud-Netflix-05-Ribbon 负载均衡

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 SpringCloud-Netflix-05-Ribbon 负载均衡,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文


五、Netflix Ribbon 负载均衡

5.1 Ribbon 简介

Netflix Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST请求自动转换成客户端负载均衡的服务调用。微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的;

Ribbon的主要作用就是两个:

1)服务之间调用

2)服务调用时的负载均衡

5.2 Ribbon 快速入门

5.2.1 Ribbon 服务负载均衡

Ribbon已经被被集成到Eureka中,我们之前在学习Eureka时就已经用过了Ribbon了;

在RestTemplate上添加@LoadBalanced注解之后,调用接口便自动继承了负载均衡的能力;

  • ItemApplication:
package com.cloud.item;

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.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@SpringBootApplication
@EnableDiscoveryClient      // 开启服务发现功能
@EnableEurekaClient         // 开启Eureka客户端
public class ItemApplication {
    public static void main(String[] args) {
        SpringApplication.run(ItemApplication.class);
    }

    @Bean
    @LoadBalanced           // 负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  • ItemController:
package com.cloud.item.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@RestController
@RequestMapping("/item")
public class ItemController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/findOrderById/{orderId}")
    public Map findOrderById(@PathVariable Integer orderId){

        // 使用RestTemplate进行远程调用
        Map resultMap = restTemplate.getForObject("http://order-service/order/" + orderId, Map.class);

        return resultMap;
    }
}
  • OrderController:
/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Value("${spring.cloud.client.ip-address}")
    private String ip;

    @Value("${server.port}")
    private String port;

    @GetMapping("{id}")
    public Map findById(@PathVariable Integer id){

        return new HashMap(){{
            put("flag",true);
            put("message","查询成功"+ip+":"+port);
            put("statusCode","200");
            put("id",id);
        }};
    }
}

启动两个Order服务,访问:http://localhost:9001/item/findOrderById/1

在这里插入图片描述

多次访问,查看是否有轮询效果;

5.2.2 自定义服务列表

当我们在 RestTemplate上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,关系如下:

在这里插入图片描述

有的时候我们希望Ribbon可以跳过Eureka,直接使用IP+端口的方式调用服务,这样的我们就不需要借助Eureka提供的服务名来远程调用了(测试环境用),我们可以自定义服务列表来实现负载均衡;

关闭Ribbon与Eureka的集成:

ribbon:
  eureka:
    enabled: false                # 关闭与Eureka的集成
ribbon-order-service:             # 自定义服务名称
  ribbon:
    listOfServers: localhost:9001,localhost:9002      # 服务的主机列表

注意:默认情况下Ribbon与Eureka的集成为开启状态,在开启状态下,只能使用服务名调用;而在关闭状态下,只能使用IP+端口来调用,如果指定IP+端口的方式来调用,那么必定不能提供负载均衡的功能;如果想使用负载均衡功能,那么必须自定义服务名称,并为该服务配置主机列表;

  • ItemController:
@GetMapping("/findOrderById/{orderId}")
public Map findOrderById(@PathVariable Integer orderId){

    // 使用自定义的服务名称
    Map resultMap = restTemplate.getForObject("http://ribbon-order-service/order/" + orderId, Map.class);

    return resultMap;
}
  • OrderController:
package com.cloud.order.controller;

import com.cloud.order.entity.Order;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Value("${spring.cloud.client.ip-address}")
    private String ip;

    @Value("${server.port}")
    private String port;

    @GetMapping("{id}")
    public Map findById(@PathVariable Integer id) {

        return new HashMap() {{
            put("flag", true);
            put("message", "查询成功" + ip + ":" + port);
            put("statusCode", "200");
            put("id", id);
        }};
    }
}

5.3 Ribbon的配置

5.3.1 Ribbon 的属性配置

Ribbon的所有的默认配置可以去com.netflix.client.config.DefaultClientConfigImpl类下找:

关于Ribbon的所有配置在com.netflix.client.config.CommonClientConfigKey中定义:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XHQ8xA2R-1647869038595)(media/171.png)]

5.3.2 Ribbon常用配置

5.3.2.1 连接配置

ribbon:
  ConnectTimeout: 2000           # 请求连接的超时时间
  ReadTimeout: 5000               # 请求处理的超时时间
  • ConnectTimeout:是指请求发送到服务,两端连接所需要的时间

  • ReadTimeout:是指建立连接后从服务端读取到可用资源所用的时间

5.3.2.2 懒加载配置

Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易出现第一次调用超时,之后就调用正常的现象;

ribbon:
  eager-load:
    enabled: true                               			# 开启立即加载客户端
    clients: ribbon-order-service,ribbon02-order-service 	# 选择指定的服务开启立即加载

5.3.2.3 并发调整

ribbon:
  MaxTotalConnections: 500        # 最大连接数
  MaxConnectionsPerHost: 100      # 每个host最大连接数

5.3.3 Ribbon 配置策略

Ribbon的配置分为全局配置和指定客户端配置,两种配置格式不同;

全局配置针对于所有的服务,客户端配置只针对于具体服务使用;

  • 全局配置:
ribbon:
  ConnectTimeout: 20000           # 请求连接的超时时间
  ReadTimeout: 5000               # 请求处理的超时时间
  • 客户端配置:
ribbon-order-service:             					  # 自定义服务名称
  ribbon:
    listOfServers: localhost:9001,localhost:9002      # 服务的主机列表
    ConnectTimeout: 20000
    ReadTimeout: 5000

Tips:全局配置只针对集成Eureka时的调用,不能作用于自定义微服务名称调用;

5.4 Ribbon的负载均衡策略

5.4.1 Ribbon负载均衡策略

不难发现,我们之前使用Ribbon的负载均衡策略都是轮询;在Ribbon中,除了轮询策略外,还提供有其他几种策略,内部负责负载均衡的顶级接口为com.netflix.loadbalancer.IRule

SpringCloud-Netflix-05-Ribbon 负载均衡

  • com.netflix.loadbalancer.RoundRobinRule

    • **轮询策略;**以轮询的方式进行负载均衡。
  • com.netflix.loadbalancer.WeightedResponseTimeRule

    • **权重策略;**会计算每个服务的权重,响应速度越快的实例选择权重越大,越高的被调用的可能性越大。
  • com.netflix.loadbalancer.ResponseTimeWeightedRule

    • **权重策略;**作用和WeightedResponseTimeRule一致,后来改名为 WeightedResponseTimeRule
  • com.netflix.loadbalancer.BestAvailableRule

    • **最佳策略;**首先过滤掉故障实例,在没有故障的实例中,选择一个压力最小(并发量)的服务
  • com.netflix.loadbalancer.ZoneAvoidanceRule

    • **回避策略;**使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 来判断是否选择某个 Server,前一个判断判定一个 Zone 的运行性能是否可用,剔除不可用的 的所有 Server,AvailabilityPredicate 用于过滤掉连接数过多的 Server。
  • com.netflix.loadbalancer.AvailabilityFilteringRule

    • **过滤策略;**过滤掉故障和请求数超过阈值的服务实例,再从剩下的实例中轮询调用。
  • com.netflix.loadbalancer.RandomRule

    • **随机策略;**在服务列表中随机选择一个服务调用;
  • com.netflix.loadbalancer.RetryRule

    • **重试策略;**在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内服务未响应,则继续使用轮询方式访问其他服务;

5.4.1 修改Ribbon负载均衡策略

  • 配置文件方式修改负载均衡策略:基于自定义服务名调用
ribbon:
  eureka:
    enabled: false                # 关闭与Eureka的集成
ribbon-order-service:     		# 只修改ribbon-order-service这个服务的负载均衡策略
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule			# 随机策略
    listOfServers: localhost:9001,localhost:9002,localhost:9003      # 服务的主机列表
  • 基于Eureka服务名调用:
ribbon:
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  • 配置类方式修改负载均衡策略:
/**
 * 随机策略
 * @return
 */
@Bean
public RandomRule randomRule(){
    return new RandomRule();
}

tips:同时指定了配置文件和类的方式时,以加载的负载均衡类为准;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131748.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!