ribbon-客户端负载均衡

简介: ribbon-客户端负载均衡

一. 客户端负载均衡器Ribbon



1. 什么是服务端负载均衡


之前研究nacos的时候也说过服务端负载均衡和客户端负载均衡. 其实我们常用的服务端负载均衡就是nginx

 

在负载均衡中维护一个可用的服务实例清单, 当客户端请求来临时, 负载均衡服务器按照某种配置好的规则(负载均衡算法), 从可用服务实例清单中, 选取其一去处理客户端请求, 这就是服务端负载均衡, 例如Nginx. 通过nginx进行负载均衡, 客户端发送请求值Nginx, nginx通过负载均衡算法, 在多个服务器之间选择一个进行访问.


1187916-20200709171355910-395849697.png


2. 什么是客户端负载均衡


接下来, 我们要讲的ribbon, 就属于客户端负载均衡, 在ribbon客户端会有一个服务实例地址列表, 在发送请求前, 通过负载均衡算法, 选择一个服务实例, 然后进行访问, 这是客户端负载均衡. 即在客户端进行负载均衡算法分配.


1187916-20200709171430713-1750256449.png


3. 客户端负载均衡的用法


先面我们先来看看ribbon负载均衡的效果


第一步: 添加依赖


我么拷贝了一个order项目, 为其添加ribbon依赖


<dependency>
    <groupId>org.springframework.cloud</groupId>           
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

image.png


第二步: 增加注解: @LoadBalance

1187916-20200709173533270-874103161.png


这里在实例化RestTemplate的时候, 增加一个注解@LoadBalanced.


我们之前在研究zuul的时候, 好像没有配置过这个注解呀, 为什么呢?因为在zuul里调用的时候使用feign, feign里面实现了这个负载均衡.


第三步: 在order服务中调用product服务, 使用的是restTemplate方式调用


package com.lxl.www.gateway.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@Slf4j
@RestController
public class UserController {
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("get/user")
    public String getUser() {
        String forObject = restTemplate.getForObject("http://product/config", String.class);
        System.out.println(forObject);
        return forObject;
    }
}


第四步: 验证效果


启动order服务1台-里面添加了ribbon依赖配置, 端口号是8080

启动product服务3台, 端口号分别是8081, 8082, 8083

1187916-20200709173910736-1341628106.png

product的详情信息

1187916-20200709173940566-499411669.png


请求服务


http://localhost:8080/get/order

1187916-20200709174148426-667132618.png


我们看到调用了3次, 每个实例被调用1次


二. 配置ribbon负载均衡策略



我们看到了ribbon的基本用法, 知道他的一个基本的实现原理, 下面来看看ribbon的基本配置


1. ribbon默认的负载均衡策略

1187916-20200709193340429-1080361168.png


ribbon自带的负债均衡策略一共有6中


  • RandomRule: 是随机策略
  • RoundRobinRule: 轮询策略
  • RetryRule: 重试策略
  • ZoneAvoidanceRule: 地域内轮询策略(默认策略). 这里zone在亚马逊服务器上有,在阿里云上没有这个概念, 所以可以不考虑zone, 那么这个策略相当于轮询.
  • PredicateBaseRule:
  • WeightedResponseTimeRule: 权重响应策略

最后我们来看看这些策略的具体实现


2. 修改系统默认的负债均衡策略, 默认的是轮询, 我们将其修改为随机策略

1187916-20200713202106959-1602761483.png


其实很简单, 我们重新指定IRule规则即可, 这里设置的是随机策略.


后面在配置文件中也可已设置每一个项目的负载均衡策略. 但是如果这里和配置文件都设置了, 那么以这里的为准

 

3. ribbon的细粒度自定义配置


比如,现在有一个场景, 有三个服务, 一个订单, 一个产品, 一个交易

订单调用产品采用的负载均衡策略是轮询, 订单调用交易服务采用的负载均衡策略是随机



1187916-20200713194108948-170523993.png


怎么办呢? 我们可以在配置文件中配置每一个服务的负载均衡策略, 我们来看看如何做呢?


有两种方案, 方案一, 写java类实现. 方案二, 通过配置实现


方案一:


第一步, 我们自定义需要配置的类, 重点: 这些类不能够被系统扫描到


所谓的不能被扫描到指的是, 不能被启动类Application扫描到, 那么就要放在其外面的子包里面.


(一旦被系统扫描到, 就变成了一个全局的配置类)

我们开一下如何配置

image.png

第二步: 这里定义了两个配置类Customerconfiguration和ProductConfiguration, 其中customer使用的是RandomRule()随机策略, 而Product使用RoundRobinRule()策略.

@Configuration
public class ProductConfiguration {
    @Bean
    public IRule getRule() {
        return new RoundRobinRule();
    }
}
@Configuration
public class CustomerConfiguration {
    @Bean
    public IRule getRule() {
        return new RandomRule();
    }
}


然后自定义一个配置文件CustomeRibbonConfig, 并指定每个项目使用的负载均衡策略

1187916-20200713204802391-569064677.png


第三步:运行项目


启动三台product, 三台customer ,一台gateway

1187916-20200713205209277-1770256461.png

然后访问链接


http://localhost:8080/get/product

http://localhost:8080/get/customer


可以看到一个是轮询的效果, 一个是随机的效果


方案二:


重点:  我们还有一种简单的基于配置的方法. (推荐使用)

# 所有项目公用的配置策略
ribbon:
  NFLoadBalancerRuleClassName:  com.netflix.loadbalancer.RoundRobinRule
# 带有项目名称的ribbon配置,仅对某个项目生效
product:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
customer:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

4. ribbon配置详解

ribbon:  ReadTimeout: 1000  ConnectTimeout: 1000  MaxAutoRetries: 1  MaxAutoRetriesNextServer: 2  OkToRetryOnAllOperations: false  http:     client:      enabled: true

MaxAutoRetries的含义?


每一台服务器重试的次数, 不包含首次调用的那一次


ribbon.MaxAutoRetries=1

含义是如果调用服务失败了, 那么重试1次


MaxAutoRetriesNextServer的含义:


重试服务器的个数, 不包含首次调用的那一台实例


ribbon.MaxAutoRetriesNextServer=2

含义是是: 如果负载均衡选择了服务器1, 结果调用失败, 重试还是失败了. 那么这是可以选择重试除了这台服务器的其他服务器. 可以重试几台呢? 可以重试两台


OkToRetryOnAllOperations的含义


这里是对http方法进行重试设置, 可以设置成true或者false


如果设置为true: 则表示post,put等方法也会进行重试. 这样会导致的问题是, 重复提交. 要避免这个事情的发生, 要保证服务的幂等性


什么是服务的幂等性呢?

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
1月前
|
负载均衡 算法
ribbon的7种负载均衡算法和替换方法
ribbon的7种负载均衡算法和替换方法
34 0
ribbon的7种负载均衡算法和替换方法
|
4月前
|
JSON 负载均衡 Java
Spring Cloud Ribbon:负载均衡的服务调用
Spring Cloud Ribbon:负载均衡的服务调用
64 0
|
1月前
|
负载均衡 算法 Java
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
|
1月前
|
负载均衡 程序员 微服务
【微服务】2、一篇文章详解 Ribbon 负载均衡
【微服务】2、一篇文章详解 Ribbon 负载均衡
37 0
|
3月前
|
负载均衡 Java Spring
深入理解Ribbon负载均衡
深入理解Ribbon负载均衡
61 0
|
4月前
自定义Ribbon规则--客户端写法
自定义Ribbon规则--客户端写法
|
4月前
|
负载均衡 算法 Java
SpringCloud - Feign与Ribbon请求负载均衡实践
SpringCloud - Feign与Ribbon请求负载均衡实践
44 0
|
4月前
|
负载均衡 算法 Java
SpringCloud - Ribbon负载均衡入门与实战
SpringCloud - Ribbon负载均衡入门与实战
73 0
|
10天前
|
负载均衡 算法 应用服务中间件
面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
字节跳动面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
28 0
|
3月前
|
负载均衡 应用服务中间件 nginx
百度搜索:蓝易云【Nginx和tomcat实现负载均衡教程】
至此,你已经成功地使用Nginx和Tomcat实现了负载均衡。Nginx将根据配置的负载均衡策略将客户端请求分发到多个Tomcat服务器上,以提高系统的性能和可用性。请注意,在实际生产环境中,还需要进行其他配置和优化,如健康检查、会话保持等,以满足具体的需求。
34 0