SpringCloud(二)之我学 Ribbon
1、负载均衡
Ribbon 虽然不是显示的配置为一个子项目,但是无论是在 API 网关的转发请求,还是服务之间的调用 Feign ,都是通过 Ribbon 来做负载均衡的。
负载均衡,主要是为了对系统的高可用、网络压力的缓解和处理能力扩容。
2、客户端负载均衡
所有客户端节点都维护自己要访问的服务端清单,这些清单主要来源于注册中心(例如 Eureka Server),并且也是用心跳机制去维护服务端清单的健康性。
微服务中使用负载均衡只需要两步:
1)、服务提供者只需要启动多个服务实例,注册到一个注册中心,或者多个相关联的注册中心。
2)、服务消费者直接通过调用,被 @LoadBalanced 注解修饰过的 RestTemplate 来实现面向服务的接口调用。
3、原理
RestTemplate有四种不同的请求类型和多种参数类型的服务调用实现。
GET(查) 、 POST(增) 、PUT(改) 、DELETE(删) 四种请求。
常见的异服务调用: (仅举例 get 请求)
restTemplate.getForEntity(url,User.class):传入url,拼接参数。返回的对象 getBody() 就能获取到异服务调用的结果集。
restTemplate.getObejct():入参和返回值都类似 getForEntity() 方法,只是返回实例不需要再 getBody()。
源码分析:
@LoadBalanecd 注解是用来给 RestTemplate 做标记,以使用负载均衡的客户端来配置它。(LoadBalancerClient)
在 LoadBalancerClient 接口中的参数的定义:
ServiceInstance choose(String serviceId):根据传入的服务名 serviceId,从负载均衡器中挑选一个对应服务的实例。
T execute(String serviceId,LoadBalancerRequest request) throws IOException:使用从负载均衡器中挑选出的服务实例来执行请求内容。
URI reconstructURI(ServiceInstance instance,URI original):为系统构建(返回)一个合适的 host:port 形式的URI。
Ribbon 实现负载均衡自动化配置,需要满足以下两个条件:
@ConditionalOnClass(RestTemplate.class):RestTemplate 类必须存在于当前工程的环境中。
@ConditionalOnBean(LoadBalancerClient.class):在 Spring 的 Bean 工程中必须有 LoadBalancerClient 的实现 Bean。
通过 LoadBalancerInterceptor 拦截器将 RestTemplate 变成客户端负载均衡。
实现原理:被@LoadBalanced 注解修饰的 RestTemplate 对象向外发起 HTTP 请求时,会被 LoadBalancerIntercepetor 类的 intercept 函数拦截。在使用RestTemplate 时采用了服务名作为host,所以直接从 HttpRequest 的URI对象中通过 getHost() 拿到服务名,调用 execute 函数去根据服务名来选择 实例 并发起实际的请求。(实例是IP地址)
4、负载均衡策略
顶层为 IRule 规则接口,一个 AbstractLoadBalancerRule 继承了 IRule 接口,并且有一系列的实现规则。
RandomRule:根据一个随机数,去获取可用实例列表,用随机数作为下标获取一个可用服务实例。
RoundRobinRule:线性轮询方式依次选择每个服务实例。
RetryRule:重试机制的实例选择功能。内部默认使用了 RoundRobinRule 实例。设定一个时间阈值,尝试时间超过阈值就返回 null。
WeightedResponseTimeRule:对 RoundRobinRule 策略的扩展,根绝实例的运行情况,来计算权重来挑选实例,达到更优的分配效果。其中三个核心内容:
1)、定时任务,默认30秒执行一次,为每个服务实例计算权重。
2)、权重计算:计算每个实例实例平均响应时间,总平均响应时间,获取每个实例的权重区间。例如A、B、C、D 平均响应时间10,40,80,100,总230。计算A=230-10=[0,220],B=220+230-40=(220,410],C=(410,560],D=(560,690]。
结论是平均响应时间越短,权重区间宽度越大,被选中的机会越大。
3)、实例选择
ZoneAvoidanceRule:选择区域策略,过滤实例,得到可用实例。(先过滤清单,再轮询选择)
调用顺序(选择服务器逻辑): loadBalancerClient ---> ILoadBalancer(ZoneAwareLoadBalancer) 选择区域---> IRule (ZoneAvoidanceRule) 根据算法,选择具体服务实例。
自己实现一个选择服务实例的负载方法:


5、配置详解
与 Eureka 结合:Eureka 会为架构维护所有服务的实例清单。由于 Ribbon 默认实现了区域亲和策略,可以通过 Eureka 实例的元数据配置来实现区域化的实例配置方案。比如将不同机房的实例配置成不同的区域值,作为跨区域的容错机制实现。
实现也很简单,在服务实例的元数据中增加 zone 参数来指定自己所在的区域,例如:
eureka.instance.metadataMap.zone=chengdu. (配置文件)
@Bean (main 方法里)
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
在调用类里注入 RestTemplate 类,并且
restTemplate.getForEntity("URL",String.class).getBody();
6、重试机制
Eureka 的服务治理机制强调了 CAP 原理的 AP,可用性和可靠性(C 一致性)。
Eureka 为了实现更高的服务可用性,牺牲了一定的一致性。例如 Eureka 会因为超过85% 的实例丢失心跳而出发保护机制,注册中心会保留此时的所有节点。(极端情况接受故障也不丢掉“健康”实例)
为了增强对服务故障实例的容错,所以加入了重试机制。通过简单的配置,那些通过 RestTemplate 实现的服务访问,就会自动根据配置来实现重试策略。
重试次数,就是访问到故障请求,再尝试访问同一个实例,如果不行,就换一个实例访问。
这两个重试由最后两个参数决定。
SpringCloud(二)之我学 Ribbon的更多相关文章
- (二)一起学 Java Collections Framework 源码之 AbstractCollection
. . . . . 目录 (一)一起学 Java Collections Framework 源码之 概述(未完成) (二)一起学 Java Collections Framework 源码之 Abs ...
- springcloud(二) 负载均衡器 ribbon
代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo ribbon是一个负载均衡客户端 类似nginx反向代理,可 ...
- SpringCloud微服务实战——搭建企业级开发框架(十二):OpenFeign+Ribbon实现负载均衡
Ribbon是Netflix下的负载均衡项目,它主要实现中间层应用程序的负载均衡.为Ribbon配置服务提供者地址列表后,Ribbon就会基于某种负载均衡算法,自动帮助服务调用者去请求.Ribbo ...
- 【微服务】之四:轻松搞定SpringCloud微服务-负载均衡Ribbon
对于任何一个高可用高负载的系统来说,负载均衡是一个必不可少的名称.在大型分布式计算体系中,某个服务在单例的情况下,很难应对各种突发情况.因此,负载均衡是为了让系统在性能出现瓶颈或者其中一些出现状态下可 ...
- (1-2)SpringCloud:服务的消费者rest+ribbon
服务发现的任务是由Eureka客户端完成,而服务的消费任务由Ribbon完成.Ribbon是一个基于HTTP和TCP的客户端负载据衡器,它可以通过客户端中配置ribbonServerList服务端列表 ...
- springcloud(二)
springcloud路由网关 一.什么是网关 Zuul的主要功能是路由转发和过滤器.路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务.zu ...
- springcloud(二):Eureka服务注册与发现
Spring Cloud Netflix 该项目是Spring Cloud的子项目之一,主要内容是对Netflix公司一系列开源产品的包装,它为Spring Boot应用提供了自配置的Netflix ...
- 「 从0到1学习微服务SpringCloud 」04服务消费者Ribbon+RestTemplate
系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现 「 从0到1学习微服务S ...
- 【springcloud】客户端负载均衡(Ribbon)
转自:https://blog.csdn.net/pengjunlee/article/details/86594934 服务器端负载均衡负载均衡是我们处理高并发.缓解网络压力和进行服务器扩容的重要手 ...
随机推荐
- 上海月薪 1w 和家乡月薪 5000 你选择哪?
如题,这是我在知乎上看到的一个热门话题--要现在的我来回答的话,毫无疑问会选择上海,即便月薪只有 5000 也去,还要趁早去. 有读者可能会质问我:"你之前不是说在三线城市洛阳工作很爽吗?怎 ...
- 关于动态路由中路由之间的跳转(页面a跳转到页面b)
由addRouters方法获取到后台的动态路由,要实现路由之间的跳转,不可直接用path: '***',而是将动态路由存储到vuex中,再从vuex中取得,如:this.$store.menu.nav ...
- 3分钟入门lambda表达式
本节是lambda表达式的一个入门课,讲解的同时配有练习demo 前言什么是lambda表达式?基础语法函数式接口自己实现一个函数式接口jdk提供的函数式接口Consumersupplierfunct ...
- LeetCode-最长回文串
题目描述: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串. 在构造过程中,请注意区分大小写.比如 "Aa" 不能当做一个回文字符串. 注意:假设字符 ...
- gulp常用的插件
参考地址: http://www.cnblogs.com/1wen/p/5421212.html https://my.oschina.net/wolfx/blog/673905 http://www ...
- 我的MacbookPro进水了!维修过程记录
电脑进水与解决方案 如果事情有变坏的可能,不管这种可能性有多小,它总会发生.---墨菲定律 进水过程 2020年03月21日日下午3点左右,不小心把水杯碰倒了,水通过电脑右侧的键盘处进入了大概有10毫 ...
- python深浅拷贝&垃圾回收&上下文管理(with语句)
深浅拷贝 在Python中使用copy模块用于对象的拷贝操作. 该模块提供了两个主要的方法:浅拷贝 copy.copy() 深拷贝 copy.deepcopy() 1.浅拷贝(copy) 浅拷贝: 不 ...
- Chrome80调整SameSite策略对IdentityServer4的影响以及处理方案(翻译)
首先,好消息是Goole将于2020年2月份发布Chrome 80版本.本次发布将推进Google的"渐进改良Cookie"策略,打造一个更为安全和保障用户隐私的网络环境. 坏消息 ...
- Servlet(四)----HTTP、Response、servletContent
## HTTP协议: 1.请求消息:客户端发送给服务器端的数据 * 数据格式: 1.请求行 2.请求头 3.请求空行 4.请求体 2.响应消息:服务器端发送给客户端的数据 * 数据格式: ...
- 洛谷 P2568 GCD 题解
原题链接 庆祝一下:数论紫题达成成就! 第一道数论紫题.写个题解庆祝一下吧. 简要题意:求 \[\sum_{i=1}^n \sum_{j=1}^n [gcd(i,j)==p] \] 其中 \(p\) ...