Skip to content

负载均衡-Ribbon

什么是负载均衡(Load Balance)

当访问的服务具有多个实例时,需要根据某种“均衡”的策略决定请求发往哪个节点,这就是所谓的负载均衡,原理是将数据流量分摊到多个服务器执行,减轻每台服务器的压力,从而提高了数据的吞吐量。比如:订单服务部署了3个节点,在访问订单服务时,访问哪一个节点是根据负载均衡策略来决定的。
软硬件角度负载均衡的种类

  • 通过硬件来进行解决,常见的硬件有NetScaler、F5、Radware和Array等商用的负载均衡器,但比较昂贵的
  • 通过软件来进行解决,常见的软件有LVS、Nginx等,它们是基于Linux系统并且开源的负载均衡策略

从端的角度负载均衡有两种

  • 服务端负载均衡:请求到视频服务的负载均衡,来决定访问哪个视频服务节点
  • 客户端负载均衡:在订单服务做负载均衡,来决定调用视频服务的哪个节点

常见的负载均衡策略(看组件的支持情况)

  • 节点轮询
    • 简介:每个请求按顺序分配到不同的后端服务器
  • weight 权重配置
    • 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
  • 固定分发
    • 简介:根据请求按访问ip的hash结果分配,这样每个用户就可以固定访问一个后端服务器
  • 随机选择、最短响应时间等等

什么是Ribbon

Ribbon是springcloud下的客户端负载均衡器,消费者在通过服务别名调用服务时,需要通过Ribbon做负载均衡获取实际的服务调用地址,然后通过httpclient的方式进行本地RPC远程调用。

订单服务增加负载均衡

添加注解@LoadBalanced

java
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    //注入RestTemplate时加入@LoadBalanced注解,代表RestTemplate具有负载均衡的功能
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

在common公共服务的Video.java实体类中添加一个字段,用于测试负载均衡

java
//测试使用 - 服务信息
private String serverInfo;

public String getServerInfo() { return serverInfo; }
public void setServerInfo(String serverInfo) { this.serverInfo = serverInfo; }

修改VideoController,记录请求信息

java
//只加了一行控制台打印
@GetMapping("/find_by_id")
public Object findById(int videoId, HttpServletRequest request){
    System.out.println("视频服务:" + request.getServerName() + ":" + request.getServerPort());
    return videoService.findById(videoId);
}

启动3个视频服务,启动时记得修改端口,9000,9001,9002
idea软件1个项目启动多个实例,需要设置,设置后启动3个视频服务:


修改订单服务Controller

java
//将之前通过DiscoveryClient获取服务IP和端口的方式更改为服务名称的方式

@GetMapping("/save")
public Object save(int videoId){
    //拼接URL,将IP和端口改为视频服务的名称
    String url = "http://class-video-service/api/v1/video/find_by_id?videoId=" + videoId;
    //网络请求
    Video video = restTemplate.getForObject(url, Video.class);
    VideoOrder videoOrder = new VideoOrder();
    videoOrder.setVideoId(videoId);
    videoOrder.setVideoTitle(video.getTitle());
    videoOrder.setCreateTime(video.getCreateTime());
    return videoOrder;
}

启动1个订单服务,启动后查看Nacos控制台

访问订单服务接口测试,多访问几次后查看视频服务的控制台是否实现负载均衡调用(默认轮询的方式调用)

java
http://localhost:8000/api/v1/video_order/save?videoId=40

自定义Ribbon负载均衡策略

Ribbon支持的负载均衡策略介绍

策略类命名描述
RandomRule随机策略随机选择server
RoundRobinRule轮询策略按照顺序选择server(默认)
RetryRule重试策略当选择server不成功,短期内尝试选择一个可用的server
AvailabilityFilteringRule可用过滤策略过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)
WeightedResponseTimeRule响应时间加权重策略根据server的响应时间分配权重,以响应时间作为权重,响应时间越短的服务器被选中的概率越大,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule区域权重策略综合判断server所在区域的性能,和server的可用性,轮询选择server

订单服务增加配置,调用视频服务采用随机策略

java
class-video-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

策略选择:

  1. 如果每个机器配置一样,则建议不修改策略 (推荐)
  2. 如果部分机器配置强,则可以改为 WeightedResponseTimeRule