背景知识
负载均衡的概念
- 可以参考 Dubbo 的负载均衡
- 简单来说就是将用户的请求平摊的分配到多个服务上,从而达到系统的高可用。常见的负载均衡有软件 Nginx、LVS、硬件 F5 等
负载均衡的分类
- 进程内的负载均衡:将负载均衡逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。它属于一个类库,集成于消费方进程,消费方通过它来获取服务提供方的地址。例如:Ribbon
- 集中式的负载均衡:在服务的消费方和提供方之间使用独立的负载均衡设施,由该设施负责把访问请求通过某种策略转发至服务的提供方。例如:F5、Nginx
Ribbon
概念
- SpringCloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端负载均衡的工具
- Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon 客户端组件提供一系列完善的配置项如连接超时,重试等。简单来说,就是在配置文件中列出 LoadBalancer 后面所有的机器,Ribbon 会自动的帮助你基于某种规则(简单轮询、随机连接等)去连接这些机器。同时我们也很容易使用 Ribbon 实现自定义的负载均衡算法
使用
- Ribbon 是一个软负载均衡客户端组件,可以和其他客户端结合使用,例如:Eureka。
- 但是 spring-cloud-starter-netflix-eureka-client 3.0版本以上已经将 Ribbon 替换成了 LoadBalancer,所以需要我们手动添加依赖 spring-cloud-starter-netflix-ribbon
- Maven 仓库地址
实质
- 负载均衡 + RestTemplate
- RestTemplate 有很多方法:getForObject()、getForEntity()、postForObject()、postForEntity()
- Object 返回的是 JSON,Entity 返回的是 ResponseEntity 对象(响应头、状态码、响应体)等信息
- RestTemplate 官网
负载均衡算法
- RoundRobinRule:轮询
- RandomRule:随机
- RestryRule:先按照 RoundRobinRule 策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
- WeightedResponseTimeRule:对 RoundRobinRule 的拓展,响应速度越快的实例选择权重越大,越容易被选择
- BestAvailableRule:会先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
- AvailabilityFilteringRule:会先过滤故障实例,再选择并发较小的实例
- ZoneAvoidanceRule:默认规则,复合判断 server 所在区域的性能和 server 的可用性选择服务器
更改默认的算法
- 注意不能放在 @ComponentScan 所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。
- 手写一个@Configuration配置类,返回对应的算法
- 在对应的 @Controller 层或者主启动类上面添加 @RibbonClient 注解
自定义算法
- 在配置类里面写对应的规则
- 通过 @DiscoveryClient 获取对应服务名的所有服务
Ribbon 与 Nginx 的区别
- Ribbon 是本地负载均衡客户端,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到 JVM 本地,从而在本地实现 RPC 远程服务调用技术
- Nginx 是服务器负载均衡,客户端所有请求都会交给 Nginx,然后由 Nginx 实现转发请求。也就是负载均衡是由服务端实现的
缺点
- ribbon 官网地址
- 目前处于维护状态,后期致力于将 LoadBalancer 平替 Ribbon
遇到问题
- 使用 SpringCloud3.0 以上版本还仍然想用 ribbon 的时候,会出现我的服务已经成功注册到eureka server 中了,而 ribbon 服务器找不到已经注册的服务。猜测的因为 ribbon 服务器没有在eureka server中注册成功,所以不能识别主机名称。
- 翻阅解决的主要方式就是降低版本配置
- eureka中显示有服务但是通过ribbon调用显示No instances available for service-hello的问题
- Ribbon and Eureka - No instances available
OpenFeign
Feign 概念
- Feign 是一个声明式 WebService 客户端。使用 Feign 能让编写 WebService 客户端更加简单,更容易
- Feign 内置了 Ribbon,用来做客户端的负载均衡,去调用服务注册中心的服务。不同的是,Feign 进一步封装,只需要通过定义服务绑定接口且以声明式的方法,从而完成服务调用。有点类似于 Dubbo
- 前面在使用 Ribbon + RestTemplate 时,利用 RestTemplate 对 http 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign 在此基础上做了进一步封装,有他来帮助我们定义和实现依赖服务接口。在 Feign 的实现下,我们只需要创建一个接口并使用注释的方式来配置它,即可完成对服务提供者的接口绑定,简化了使用 Ribbon 时,自动封装服务调用客户端的开发量
OpenFeign 概念
- 在 Feign 的基础上支持 SpringMVC 注解 @RequestMapping 等等。可以通过 @FeignClient 解析 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
- 新版本的 OpenFeign 已经不在内置 Ribbon
使用
- Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节。也就是对 Feign 接口的调用情况进行监控和输出
- Feign 也可以对超时进行配置

京公网安备 11010502036488号