Spring Cloud Ribbon (二)

客户端负载均衡 Spring Cloud Ribbon

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现,可以将面向服务的REST模板请求自动转换为客户端负载均衡的服务调用。

1. 客户端负载均衡

负载均衡在系统架构中是一个非常重要且不得不去实施的内容。负载均衡是对系统的高可用,网络压力的缓解和处理能力的扩容的重要手段之一。通常所说的负载均衡是指服务端负载均衡,而客户端负载均衡和服务端负载均衡最大的不同点在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都维护着自己要访问的服务端清单,也需要心跳去维护服务端清单的健康性,只是需要与注册中心配合完成。

1.1 使用客户端负载均衡调用

  • 服务提供者启动多个服务实例并注册到一个或多个相关联的服务注册中心
@Bean
@LoadBelanced
RestTemplate restTemplate() {
  return new RestTemplate();
}
  • 服务消费者通过调用被@LoadBalanced注解修饰的RestTemplate来实现面向服务的接口调用
@Autowired
private RestTemplate restTemplate;

@RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
public String helloConsumer() {
  return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
}

1.2 RestTemplate详解

RestTemplate对象会使用Ribbon的自动化配置,同时通过配置@LoadBalanced开启客户端的负载均衡。

RestTemplate针对不同请求类型和参数类型的服务调用实现请参见JDK文档。

2. 负载均衡策略及配置

2.1 负载均衡策略

在Ribbon中实现了非常多的选择策略(IRule接口的各个实现)

  • RandomRule:随机选择策略
    该策略实现了从服务实例清单中随机选择一个服务实例,具体的选择逻辑在一个while(server == null)循环之内,若出现死循环获取不到服务实例时,很有可能存在并发的bug。
  • RoundRobinRule:线性轮询选择策略
    该策略实现了按照线性轮询的方式依次选择每个服务实例,与随机策略除获取实例逻辑不同外,在循环条件中新增一个计数器,当一直获取不到实例超过10次就会结束尝试。而线性轮询的实现是通过AtomicInteger nextServerCyclicCounter对象实现,每次进行实例选择时调用incrementAndGetModulo函数实现递增。
  • RetryRule:具备重试机制的选择策略
    该策略实现了一个具备重试机制的实例选择,在其内部定义了一个IRule对象,默认使用了RoundRobinRule选择策略。实现了对内部选择策略进行反复尝试的策略,若期间能选择到具体服务实例就返回,否则根据根据设置的尝试结束时间为阈值(maxRetryMills参数定义的值 + choose方法开始执行的时间戳),当超过该阈值返回null。
  • WeightResponseTimeRule:加权选择策略
    该策略是对RoundRobinRule的扩展,增加了根据实例的运行情况来计算权重,并根据权重来挑选实例,它的实现主要有三个核心内容。
    1. 定时任务:WeightResponseTimeRule策略在初始化的时候会启动一个定时任务,用来为每个服务实例计算权重,该任务默认每30秒执行一次
    2. 权重计算:通过maintainWeights函数实现。先根据LoadBalancerStats记录每个实例的统计信息,累加所有实例的平均响应时间得到总平均响应时间totalResponseTime,再为实例清单逐个计算权重,规则为 weightSoFar + totalResponseTime - 实例平均响应时间,其中weightSoFar初始化为0,且每计算好几个权重需要累加到weightSoFar上供下一次计算使用。需要注意的是权重值只是表示各实例的权重区间,并非每个实例的优先级,因此不是数值越大选中概率越大。
    3. 实例选择:生成[0, 最大权重值)区间的随机数,遍历权重列表,若权重值大于等于随机数则用当前权重列表的索引获取服务实例。
  • BestAvailableRule:最空闲连接
    该策略利用LoadBalancerStats中保存的实例统计信息,通过遍历负载均衡器中维护的所有服务实例,过滤故障的实例并找出请求数最小的实例。

2.2 负载均衡配置

2.2.1 自动化配置

​ 在引入Spring Cloud Ribbon依赖后,构建以下接口的实现

interface description default
IClientConfig Ribbon客户端配置 com.netflix.client.config.DefaultClientConfigImpl
IRule Ribbon负载均衡策略 com.netflix.loadbalancer.ZoneAvoidanceRule
IPing Ribbon实例检查策略 com.netflix.loadbalancer.NoOpPing
ServerList<Server> 服务实例清单维护机制 com.netflixloadbalancer.ConfigurationBasedServerList
ServerListFilter<Server> 服务实例清单过滤机制 org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter
ILoadBalancer 负载均衡器 com.netflix.loadbalancer.ZoneAwareLoadBalancer

修改Ribbon实例检查策略示例

@Configuration
public class MyRibbonConfiguration {

  @Bean
  public IPing ribbonPing(IClientConfig config) {
    return new PingUrl();
  }
}

2.2.2 Camden版本对RibbonClient配置优化

在Camden版本中,Spring Cloud Ribbon对RibbonClient定义个性化配置的方法做了进一步优化。可以直接通过<clientName>.ribbon.<key>=<value>的形式进行配置(<clientName>.可省略表示全局配置)。配置名配置的对应接口

key description
NFLoadBalancerPingClassName 配置IPing接口的实现
NFLoadBalancerClassName 配置ILoadBalancer接口的实现
NFLoadBalancerRuleClassName 配置IRule接口的实现
NIWSServerListClassName 配置ServerList接口的实现
NIWSServerListFilterClassName 配置ServerListFilter接口的实现

修改Ribbon实例检查策略示例
服务名.ribbon.NFLoadBalancerPingClassName=com.netflix.loadbalancer.PingUrl

2.2.3 与Eureka结合

当在Spring Cloud的应用中同时引入Spring Cloud Ribbon和Spring Cloud Eureka依赖时,会触发Eureka中实现的对Ribbon的自动化配置。在与Spring Cloud Eureka结合使用时,配置将更加简单,不在需要需要通过类似<clientName>.ribbon.<key>=<value>的参数指定具体的服务实例清单。而对于Ribbon的参数配置,依然可使用2.2.2中的两种配置方式,对于客户端的配置方式可直接使用Eureka中的服务名作为<client>完成针对某个微服务的个性配置。

Spring Cloud Ribbon默认实现了区域亲和策略,可以通过Eureka实例的元数据配置来实现区域化的实例配置方案。
如:eureka.instance.metadataMap.zone=shanghai

在Spring Cloud Ribbon和Spring Cloud Eureka结合的工程中,可以通过参数配置的方式禁用Eureka对Ribbon服务实例的维护实现。
如:ribbon.eureka.enabled=false

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354