Ribbon负载均衡

引言


做核酸,一开始一个队,队很长速度很慢;后续做了相关优化,多个队做核酸,这样比之前速度增加了,比较快,但还有问题一些,如有的队长,有的队短,这样又做了一次优化;加了协调人员,由协调人员安排到哪个队作核酸,保证每个队人数差不多,避免有一些队出现拥挤的情况。

问题


provider服务:由于特定原因需要增加服务,provider服务做集群,consumer服务调用多个provider服务存在调用一些问题:

1、consumer服务怎么能调用到所有的provider服务

2、怎么实现服务的负载均衡

provider服务集群实现负载均衡

1、provider服务返回信息增加端口来区分调用哪个服务

@RestController
public class ProviderController {

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

    @RequestMapping(value = "/provider/{id}")
    public String provider(@PathVariable String id){
        return "provider id = " + id + " port = " + port;
    }
}

2、provider服务启动两次,第二次启动修改端口,

Eureka-server监控面板:

4、访问http://localhost:8280/consumerRestDiscovery/1,运行结果

我们启动了两个provider,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问。

多次访问发现无法访问到两个provider服务接口,只能返回一个provider服务接口信息。

3、解决方案:

硬件负载均衡:比如 F5、深信服、Array 等;

软件负载均衡:比如 Nginx、LVS、HAProxy 等;

硬件负载均衡或是软件负载均衡,都会维护一个可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点。当客户端发送请求到负载均衡设备的时候,该设备按某种算法(比如轮询、权重、 最小连接数等)从维护的可用服务端清单中取出一台服务端的地址,然后进行转发。

Ribbon


Eureka帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。

什么是Ribbon:客户端负载均衡组件

开启负载均衡


1、Eureka中已经集成了Ribbon,所以我们无需引入新的依赖,直接修改代码。

2、spring-consumer的引导类,在RestTemplate的配置方法上添加@LoadBalanced注解

@Bean
@LoadBalanced  //不添加这个注解,不能直接用服务名访问
public RestTemplate getRestTemplate(RestTemplateBuilder builder){
    return builder.build();
}

3、修改调用方式,不再手动获取ip和端口,而是直接通过服务名称调用:

@RestController
public class UserController {

    @Autowired
    private RestTemplate restTemplate;
    
    @RequestMapping(value = "/consumerLoadBalanced/{id}")
    public String consumerLoadBalanced(@PathVariable String id){
        String url = "http://spring-provider/provider/" + id;
        String consumer = restTemplate.getForObject(url, String.class);
        return "LoadBalanced restTemplate consumer " + consumer;
    }

}

4、运行结果:

第一次调用结果
第二调用结果

Ribbon 的超时和超时重试


Ribbon 是有超时设置,以及超时之后的重试功能的。但是,在 RestTemplate 和 Ribbon 结合的方案中,Ribbon 的超时设置和重试设置的配置方式一直在变动,因此有很多『配置无效』的现象,十分诡异。

考虑到我们在后续的项目中不会使用 RestTemplate 和 Ribbon 整合,而是使用 OpenFeign ,因此,这里就不展开解释了。

Ribbon 的饥饿加载


默认情况下,服务消费方调用服务提供方接口的时候,第一次请求会慢一些,甚至会超时,而之后的调用就没有问题了。

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

你可以通过启用 Ribbon 的饥饿加载(即立即加载)模式,并指定在项目启动时就要加载的服务:

ribbon:
  eager-load:
    enabled: true   # 开启饥饿加载
    clients: spring-provider, xxx        # (服务名)需要饥饿加载的服务

负载均衡策略


Ribbon 内置了 7 种负载均衡策略,它们都直接或间接实现了 IRule 接口:

https://blog.csdn.net/weixin_45717638/article/details/120111957

https://blog.csdn.net/m0_70565884/article/details/124929627

1.轮询策略

轮询策略:RoundRobinRule,按照一定的顺序依次调用服务实例。比如一共有 3 个服务,第一次调用服务 1,第二次调用服务 2,第三次调用服务 3,依次类推。此策略的配置设置如下:

spring-provider: # nacos中的服务id  
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #设置负载均衡
格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName,值就是IRule的实现类。

2.权重策略

权重策略:WeightedResponseTimeRule,根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。它的实现原理是,刚开始使用轮询策略并开启一个计时器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高被选中的概率也越大。此策略的配置设置如下:

spring-provider: # nacos中的服务id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

3.随机策略

随机策略:RandomRule,从服务提供者的列表中随机选择一个服务实例。此策略的配置设置如下:

spring-provider: # nacos中的服务id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

4.最小连接数策略

最小连接数策略:BestAvailableRule,也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的⼀个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取。此策略的配置设置如下:

spring-provider: # nacos中的服务id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #设置负载均衡

5.重试策略

重试策略:RetryRule,按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null。此策略的配置设置如下:

ribbon:
  ConnectTimeout: 2000 # 请求连接的超时时间
  ReadTimeout: 5000 # 请求处理的超时时间
spring-provider: # nacos 中的服务 id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #设置负载均衡

6.可用性敏感策略

可用敏感性策略:AvailabilityFilteringRule,先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例。此策略的配置设置如下:

spring-provider: # nacos中的服务id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule

7.区域敏感策略

区域敏感策略:ZoneAvoidanceRule,根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。此策略的配置设置如下:

spring-provider: # nacos中的服务id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule

Ribbon与Nginx的区别


Nginx是基于服务端的负载均衡,客户端所有请求统一交给 nginx,由 nginx 进行实现负载均衡请求转发,Nginx保持服务清单的同时,也负责负载均衡算法

Ribbon是从 eureka 注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地实现轮询负载均衡策略,Ribbon不负责出来服务清单,

应用场景的区别:

1、Nginx适合于服务器端实现负载均衡比如 Tomcat ,Ribbon适合与在微服务中RPC远程调用实现本地服务负载均衡,比如 Dubbo、SpringCloud 中都是采用本地负载均衡。

spring cloud的Netflix中提供了两个组件实现软负载均衡调用:ribbon和feign。

2、Ribbon

是一个基于 HTTP 和 TCP 客户端的负载均衡器,可以在客户端配置 ribbonServerList(服务端列表),然后轮询请求以实现均衡负载。

3、springcloud的ribbon和nginx有什么区别?哪个性能好?nginx性能好,但ribbon可以剔除不健康节点,nginx剔除节点比较复杂。ribbon还可以配合熔断器一起工作;

ribbon是客户端负载均衡,nginx是服务端负载均衡。客户端负载均衡,所有客户端节点都维护自己要访问的服务端清单。服务端负载均衡的软件模块会维护一个可用的服务清单;

ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值