Spring Cloud alibaba之Ribbon

2022-04-12  本文已影响0人  山巅自相见

什么是Ribbon

目前主流的负载方案分为以下两种:

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询、随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。

1.1客户端的负载均衡

例如spring cloud中的ribbon,客户端会有一个都武器地址列表,在发送请求前,通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端进行负载均衡算法分配。


客户端的负载均衡

1.2服务端的负载均衡

例如Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端进行负载均衡算法分配。


服务端的负载均衡

1.3 常见负载均衡算法

Ribbon负载均衡策略

IRule

这是所有负载均衡策略的父接口,\color{#FF0000}{里面的和新方法就是choose方法,用来选择一个服务实例。}

AbstractLoadBalancerRule

AbstractLoadBalancerRule是一个抽象类,里面主要定义了一个ILoadBalancer,就是负载均衡器,它的目的主要是\color{#FF0000}{辅助负责均衡策略选取合适的服务端实例}

修改默认负载均衡策略

随机策略


在启动类所在类的上一级目录下新建一个配置类,之所以建在这里是因为不能让包被扫描到,因为如果被扫描到,那么这个配置就成了公共的配置,谁都可以用。代码如下:

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonRandomRuleConfig {
    // 方法名一定要叫iRule
    @Bean
    public IRule iRule() {
        return new RandomRule();
    }
}

在启动类中加上@RibbonClients注解,在这个注解里配置上手动扫描。@RibbonClient中name属性是库存服务在配置文件配置的name


configuration属性指向的是刚才新建的配置类

import com.ribbon.RibbonRandomRuleConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@RibbonClients(value = {
        @RibbonClient(name = "stock-service", configuration = RibbonRandomRuleConfig.class)
})
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
        RestTemplate build = restTemplateBuilder.build();
        return build;
    }
}

然后有测试和工具的伙计们可以使用你们的测试工具,apipost或是jmeter都可以,
进行一次压测,压测配置可以参考下我这:




因为断言根据自己实际的来就行,我这接口有两种返回值


最后新建结果树,运行起两个库存服务和订单服务,开始执行



因为添加的断言中是以8003结尾的,所以不通过的HTTP请求中的响应体都是8002结尾的。可以看见在这请求的30次中红绿是不均衡的,也就是随机的请求两个库存服务。

权重轮询策略

刚才已经试了随机策略,现在再来试一下权重轮询策略。把启动类中的手动扫描注释掉,免得一会会有冲突。

@SpringBootApplication
/*@RibbonClients(value = {
        @RibbonClient(name = "stock-service", configuration = RibbonRandomRuleConfig.class)
})*/

这次是以配置文件的方式进行策略加载。application.yml中的格式:

stock-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

其中stock-service跟上文说的库存服务配置的name一样。进入到nacos管理界面,编辑订单服务,把其中一个权重调高一点。

这里需要注意一下,把其中一个权重调到10,另外一个还是默认的1,这并不代表请求订单服务11次,其中10次调用库存服务都是8003,只有一次是8002。我们可以理解为概率,权重越高,被请求的概率也就越高。

重启订单服务,再次在测试工具中进行压测



在这30次请求中不通过仅有4次,也即是说只有4次调用了8002服务,权重轮询策略配置成功。这种以配置文件配置策略的方式上文的随机策略也可以,在这里我就不试了。

自定义负载均衡策略

我们也可以自己配置负载均衡策略,当然这就需要你对所有的策略都有所了解,如果想要配置一个可以实战用的策略,这可能就需要去了解一下源码了(个人看法)。
在刚才创建的配置包中新建一个配置类,当然这个配置类可以创建到启动类的同级包下。

import com.alibaba.nacos.client.naming.utils.ThreadLocalRandom;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;

/**
 * @author 赵毅梵
 * @create 2022-04-12
 */
public class CustomRule extends AbstractLoadBalancerRule {
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    public Server choose(Object o) {
        ILoadBalancer loadBalancer = this.getLoadBalancer();
        // 获取当前请求的服务实例
        List<Server> reachableServers = loadBalancer.getReachableServers();
        int i = ThreadLocalRandom.current().nextInt(reachableServers.size());
        Server server = reachableServers.get(i);
        return server;
    }
}

在application.yml中修该下配置,指向刚才新建的类

stock-service:
  ribbon:
    #NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
    NFLoadBalancerRuleClassName: com.ribbon.CustomRule

重启下订单服务,再用测试工具进行压测


使用LoadBalancer替换Ribbon

什么是Spring Cloud LoadBalancer

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器,用来代替Ribbon。
Spring官方提供了两种负载均衡的客户端:
RestTemplate
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。
WebClient
WebClient是从Spring WebFlux 5.0版本开始提供一个非阻塞的基于响应式编程的进行Http请求的客户端工具。它的响应式编程的基于Reactor的。WebClient中提供过了标准Http请求方式对应的get、post、put和delete等方法,可以用来发起响应的请求。

上一篇 下一篇

猜你喜欢

热点阅读