Ribbon负载均衡

依赖默认eureka中集成

在RestTemplate中添加注解

@Bean
@LoadBalanced
public RestTemplate restTemplate(){
    return new RestTemplate();
}

默认RestTemplate发送请求为(模拟get请求,返回值为String,result为html):

RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://www.baidu.com", String.class);

Ribbon接管后所做的事情(具体域名或ip替换成服务名称(或集群的服务名称)):

String url = "http://orderService/hello";
String result = restTemplate.getForObject(url, String.class);

1、Ribbon怎么将 http://orderService/hello 变成 http://127.0.0.1:8080/hello 发起请求?

  1. 拦截请求
  2. 截取服务名称
  3. 借助eureka来做服务发现 list<>
  4. 通过负载均衡算法,拿到一个服务 ip port (重点)
  5. 重构url
  6. 发起请求

LoadBalancerClient 是 SpringCloud 提供的一种负载均衡客户端,Ribbon 负载均衡组件内部也是集成了 LoadBalancerClient 来实现负载均衡。

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping("/testLoadBalance")
    public void testLoadBalancer() {
        ServiceInstance choose = loadBalancerClient.choose("orderService");
    }

选择一个服务进入BaseLoadBalancer中:

    public Server chooseServer(Object key) {
        if (counter == null) {
            counter = createCounter();
        }
        // 请求次数++
        counter.increment();
        if (rule == null) {
            return null;
        } else {
            try {
                return rule.choose(key);
            } catch (Exception e) {
                logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", name, key, e);
                return null;
            }
        }
    }

 再进入ZoneAvoidanceRule的父类PredicateBasedRule.choose方法

    @Override
    public Server choose(Object key) {
        ILoadBalancer lb = getLoadBalancer();
        // 选择轮询算法
        Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
        if (server.isPresent()) {
            return server.get();
        } else {
            return null;
        }       
    }

AbstractServerPredicate.chooseRoundRobinAfterFiltering

    public Optional<Server> chooseRoundRobinAfterFiltering(List<Server> servers, Object loadBalancerKey) {
        List<Server> eligible = getEligibleServers(servers, loadBalancerKey);
        if (eligible.size() == 0) {
            return Optional.absent();
        }
        // 使用轮询算法
        return Optional.of(eligible.get(incrementAndGetModulo(eligible.size())));
    }
    private int incrementAndGetModulo(int modulo) {
        for (;;) {
            // 请求次数
            int current = nextServerCyclicCounter.get();
            // 由于请求次数加一,线程不安全,加锁
            int next = (current + 1) % modulo;
            // 乐观锁,CAS自旋锁
            if (nextServerCyclicCounter.compareAndSet(current, next))
                return next;
        }
    }

2、使用其他算法:

orderservice:  # 服務提供者的應用名稱
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  # IRule下實現類算法的全限定類名

 (1)随机策略 RandomRule:随机数选择服务列表中的服务节点Server,如果当前节点不可用,则进入下一轮随机策略,直到选到可用服务节点为止

(2)轮询策略 RoundRobinRule:按照接收的请求顺序,逐一分配到不同的后端服务器

(3)重试策略 RetryRule:在选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用 subRule 的方式选择一个可用的server;

(4)可用过滤策略 PredicateBaseRule:过滤掉连接失败 和 高并发连接 的服务节点,然后从健康的服务节点中以线性轮询的方式选出一个节点返回

(5)响应时间权重策略 WeightedRespinseTimeRule:根据服务器的响应时间分配一个权重weight,响应时间越长,weight越小,被选中的可能性越低。主要通过后台线程定期地从 status 里面读取平均响应时间,为每个 server 计算一个 weight

(6)并发量最小可用策略 BestAvailableRule:选择一个并发量最小的服务节点 server。ServerStats 的 activeRequestCount 属性记录了 server 的并发量,轮询所有的server,选择其中 activeRequestCount 最小的那个server,就是并发量最小的服务节点。该策略的优点是可以充分考虑每台服务节点的负载,把请求打到负载压力最小的服务节点上。但是缺点是需要轮询所有的服务节点,如果集群数量太大,那么就会比较耗时。

(7)区域权重策略 ZoneAvoidanceRule:综合判断 server 所在区域的性能 和 server 的可用性,使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate 用于过滤掉连接数过多的Server。

3、Ribbon配置:

ribbon:
  eager-load:
    enabled: false  # 默认false,使用懒加载,true则第一次请求去拉取eureka中服务列表
  eureka:
    enabled: true
  http:  # 使用ribbon 用的restTemplate请求(底层 java.net.HttpUrlConnection 发的请求),方便但不支持连接池
    client: # 发请求的工具有很多 HttpClient 它支持连接池,效率更高
      enabled: false #开启ribbon超时管理
  okhttp:  # 移动端轻量级请求工具
    enabled: false
  ReadTimeout: 3000 #请求超时时间
  ConnectTimeout: 3000 #连接超时时间

注意:Ribbon(ILoadBalancer接口)作用:从Eureka拉取服务列表,使用IRule算法实现客户端调用的负载均衡

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值