1.Ribbon 简介

Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可以为Ribbon实现自定义的负载均衡算法。

a. RoundRobinRule
默认的,轮询规则,也是很多高级规则中退避的一种策略
BaseLoadBalancer类中的setRule方法

b. AvailabilityFilteringRule
会过滤掉打开熔断的服务或者是高并发连接数量的服务

c. WeightedResponseTimeRule
通过服务的平均响应时间,给每一个服务一个权重,响应时间越长,权重越小,开始统计信息不足,应用轮询策略

// 开启权重配置
spring-cloud-order-service.ribbon.NFLoadBalancerRuleClassName=com.gupaoedu.springcloud.example.springclouduserservice.GpDefineIpHashRule

d. RetryRule
先按照轮询策略,如果请求服务失败,会在指定时间内(30s)进行重试

e. BestAvailableRule
先过滤掉断路器的服务,然后选择一个并发量最小的

f. RandomRule
随机获取一个服务

2. RoundRobinRule 轮询

 public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {log.warn("no load balancer");return null;}Server server = null;int count = 0;while (server == null && count++ < 10) {List<Server> reachableServers = lb.getReachableServers();List<Server> allServers = lb.getAllServers();int upCount = reachableServers.size();int serverCount = allServers.size();if ((upCount == 0) || (serverCount == 0)) {log.warn("No up servers available from load balancer: " + lb);return null;}int nextServerIndex = incrementAndGetModulo(serverCount);server = allServers.get(nextServerIndex);if (server == null) {/* Transient. */Thread.yield();continue;}if (server.isAlive() && (server.isReadyToServe())) {return (server);}// Next.server = null;}if (count >= 10) {log.warn("No available alive servers after 10 tries from load balancer: "+ lb);}return server;}

3.RandomRule 随机

 /*** Randomly choose from all living servers*/@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;}Server server = null;while (server == null) {if (Thread.interrupted()) {return null;}List<Server> upList = lb.getReachableServers();List<Server> allList = lb.getAllServers();int serverCount = allList.size();if (serverCount == 0) {/** No servers. End regardless of pass, because subsequent passes* only get more restrictive.*/return null;}int index = chooseRandomInt(serverCount);server = upList.get(index);if (server == null) {/** The only time this should happen is if the server list were* somehow trimmed. This is a transient condition. Retry after* yielding.*/Thread.yield();continue;}if (server.isAlive()) {return (server);}// Shouldn't actually happen.. but must be transient or a bug.server = null;Thread.yield();}return server;}

4.RetryRule 重试

默认先使用轮训算法(IRule subRule = new RoundRobinRule()),再使用重试算法;
默认0.5s重试一次(long maxRetryMillis = 500)

package com.netflix.loadbalancer;
import com.netflix.client.config.IClientConfig;public class RetryRule extends AbstractLoadBalancerRule {IRule subRule = new RoundRobinRule();long maxRetryMillis = 500;public RetryRule() {}public RetryRule(IRule subRule) {this.subRule = (subRule != null) ? subRule : new RoundRobinRule();}public RetryRule(IRule subRule, long maxRetryMillis) {this.subRule = (subRule != null) ? subRule : new RoundRobinRule();this.maxRetryMillis = (maxRetryMillis > 0) ? maxRetryMillis : 500;}public void setRule(IRule subRule) {this.subRule = (subRule != null) ? subRule : new RoundRobinRule();}public IRule getRule() {return subRule;}public void setMaxRetryMillis(long maxRetryMillis) {if (maxRetryMillis > 0) {this.maxRetryMillis = maxRetryMillis;} else {this.maxRetryMillis = 500;}}public long getMaxRetryMillis() {return maxRetryMillis;}@Overridepublic void setLoadBalancer(ILoadBalancer lb) {      super.setLoadBalancer(lb);subRule.setLoadBalancer(lb);}/** Loop if necessary. Note that the time CAN be exceeded depending on the* subRule, because we're not spawning additional threads and returning* early.*///具体重试代码public Server choose(ILoadBalancer lb, Object key) {long requestTime = System.currentTimeMillis();long deadline = requestTime + maxRetryMillis;Server answer = null;answer = subRule.choose(key);if (((answer == null) || (!answer.isAlive()))&& (System.currentTimeMillis() < deadline)) {InterruptTask task = new InterruptTask(deadline- System.currentTimeMillis());while (!Thread.interrupted()) {answer = subRule.choose(key);if (((answer == null) || (!answer.isAlive()))&& (System.currentTimeMillis() < deadline)) {/* pause and retry hoping it's transient */Thread.yield();} else {break;}}task.cancel();}if ((answer == null) || (!answer.isAlive())) {return null;} else {return answer;}}@Overridepublic Server choose(Object key) {return choose(getLoadBalancer(), key);}@Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {}
}

5.自定义的负载均衡算法

根据ip的hash获取访问地址

package com.example.demo;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import java.util.List;/*** 自定义根据IP的hash值取模访问服务提供者集群*/
public class CustomizeIpHashRule extends AbstractLoadBalancerRule {public Server choose(ILoadBalancer lb,Object key){if (lb==null){return null;}else {Server server = null;while (server==null){//获取可用的服务实例列表List<Server> upList = lb.getReachableServers();//获取所有的服务实例列表List<Server> allList = lb.getAllServers();int serverCount = allList.size();if(serverCount == 0){return null;}int i=ipAddressHash(serverCount);server = upList.get(i);}return  server;}}private int ipAddressHash(int serverCount) {ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();String remoteAddr = requestAttributes.getRequest().getRemoteAddr();int code = Math.abs(remoteAddr.hashCode());return code%serverCount;}@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) {}@Overridepublic Server choose(Object key) {return choose(getLoadBalancer(),key);}}

6. 配置负载均衡算法引用

spring.application.name=eureka-user-serviceserver.port=8081
eureka.client.service-url.defaultZone=http://localhost:8761/eureka,http://localhost:8762/eureka#命名规则: 服务提供者[applicationName].ribbon.NFLoadBalancerRuleClassName= 引用 负载均衡算法 路径
#eureka-product-service.ribbon.NFLoadBalancerRuleClassName = com.netflix.loadbalancer.RandomRule
#自定义负载均衡算法引用
eureka-product-service.ribbon.NFLoadBalancerRuleClassName=com.example.demo.CustomizeIpHashRule#clientName.ribbon.NFLoadBalancerClass; #配置ILoadBalancer的实现类
#lientName.ribbon.NFLoadBalancerRuleClassName; #配置IRule的实现类
#clientName.ribbon.NFLoadBalancerPingClassName; #配置IPing的实现类
#clientName.ribbon.NFWSServerListClassName;  配置ServerList的实现类
#clientName.ribbon.NIWSServerListFilterClassName; 配置ServerListFilter的实现类

ping服务器(默认10s),比重试retry30秒要快

import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.Server;public class MyPing implements IPing{@Overridepublic boolean isAlive(Server server) {System.out.println("isAlive"+server.getHost()+":"+server.getPort());return true;}
}
spring.application.name=spring-cloud-user-servicemanagement.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always# spring cloud access&secret config
# 可以访问如下地址查看: https://usercenter.console.aliyun.com/#/manage/ak
alibaba.cloud.access-key=****
alibaba.cloud.secret-key=****# 应用服务 WEB 访问端口
server.port=8088# 配置指定服务的提供者的地址列表
spring-cloud-order-service.ribbon.listOfServers=\localhost:8080,localhost:8082//ping 服务器配置
spring-cloud-order-service.ribbon.NFLoadBalancerPingClassName=com.gupaoedu.springcloud.example.springclouduserservice.MyPingspring-cloud-order-service.ribbon.NFLoadBalancerRuleClassName=com.gupaoedu.springcloud.example.springclouduserservice.GpDefineIpHashRule

Ribbon负载均衡 算法相关推荐

  1. Ribbon 负载均衡调用04——ribbon 负载均衡算法||手写轮询算法(原理+JUC)CAS+自旋锁

    RoundRobinRule.java  源码剖析 /*** Copyright 2013 Netflix, Inc.** Licensed under the Apache License, Ver ...

  2. ribbon负载均衡算法

    IRule是以下七种负载均衡算法的父接口 说明: RoundRobinRule: 默认轮询的方式 RandomRule: 随机方式 WeightedResponseTimeRule: 根据响应时间来分 ...

  3. JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡

    Ribbon负载均衡 Ribbon概述 Spring Cloude Ribbon是基于Netfilx Ribbon实现的一套客户端 负载均衡的工具,简单说,Ribbon是Netfilix发布的开源项目 ...

  4. Ribbon负载均衡原理,Feign是如何整合Ribbon的?

    文章目录 1. 什么是负载均衡? 2. Ribbon的使用 ①:自定义负载均衡策略 ②:Ribbon的饥饿加载 3. Ribbon的负载均衡原理 ①:收集带有@LoadBalanced注解的RestT ...

  5. SpringCloud[04]Ribbon负载均衡服务调用

    文章目录 Ribbon负载均衡服务调用 1. 概述 1. Ribbon是什么 2. Ribbon能做什么 2. Ribbon负载均衡演示 1. 架构说明 2. Ribbon的POM依赖 3. Rest ...

  6. Spring Cloud Alibaba - 11 Ribbon 自定义负载均衡策略(同集群优先权重负载均衡算法)

    文章目录 Pre 需求 工程 Code 继承AbstractLoadBalancerRule实现自定义Rule 随机权重策略 配置 验证 源码 Pre Spring Cloud Alibaba - 0 ...

  7. Spring Cloud Alibaba - 07 Ribbon 应用篇及内置的负载均衡算法

    文章目录 Ribbon整合三部曲 artisan-cloud-ribbon-order step1 搞依赖 step2 搞注解 (在RestTemplate上加入@LoadBalanced注解) St ...

  8. Ribbon中的负载均衡算法实现

    Ribbon响应时间权重负载均衡算法,假设有3台服务器A,B,C响应时间为10,40,80ms. 算法公式:weighsofar + 总响应时长- 本服务器平均响应时长 A:0+130-10=120 ...

  9. Ribbon默认负载均衡算法之轮训算法原理解析

    目录 此项目中用到的数据库脚本文件 父模块`cloud2020`中仅有一个`pom.xml`文件 项目结构图 `pom.xml`文件 1.创建一个微服务项目用来测试 1.1创建`cloud-api-c ...

最新文章

  1. Splay ---- 区间翻转 区间最大值 区间加 P4146 序列终结者
  2. virtualbox+vagrant学习-2(command cli)-16-vagrant snapshot命令
  3. python怎么导入本地文件_Pycharm中如何导入本地Python环境
  4. CodeForces - 1417E XOR Inverse(字典树求逆序对+分治)
  5. SAP Spartacus 4.0 源代码模式下开启 SSR,为什么会从本地去加载 all.css?
  6. 25款操作系统全面接触 [2]
  7. Unity3d通用工具类之定时触发器
  8. apache服务器性能不行,Apache服务器性能调优
  9. deeplearning.ai——TensorFlow指南
  10. GB28181国标流媒体服务语音对讲-前端页面采集语音调用接口示例
  11. vue开发必备神器:vue-devtools
  12. HDU-3533 Escape
  13. Lizard 的第一篇博客
  14. 蚂蚁区块链平台BaaS技术解析与实践
  15. 如何提取公众号文章中的音频
  16. 【Android开发经验】Android移动UI设计经验总结
  17. w7计算机防火墙无法更改,Win7系统电脑防火墙设置无法更改该怎么解决?
  18. tomcat执行shutdown报错Could not contact [localhost:8005] (base port [8005] and offset [0]). Tomcat may n
  19. 1.1 C++小游戏——创造世界
  20. python对numpy数组求导_NumPy数组计算——python

热门文章

  1. android 安全检测 动画,Android仿小米安全中心检测进度条效果
  2. CreateEvent SetEvent ResetEvent
  3. 本地连接受限制或未连接怎么办
  4. HTML5实战之《疯狂猜价格》
  5. 如何根据包名屏蔽全面屏手势
  6. 阿里笔试题破解八卦阵问题
  7. 磨牙下酒两相宜—— 越嚼越香的香酥腊牛肉
  8. 升级到big sur pd虚拟机不能联网_标配20W套装却不支持PD快充?iPad2020充电实测
  9. Java中暂停线程的方法sleep()
  10. 高德地图找房 # 编程大实践 # Python # 嵩天 # cilay