Ribbon


Ribbon

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个spring could构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的。

Ribbon是什么?

ribbon是一个http客户端,它具备了负载均衡、失败重试、ping等功能。比如httpclient就是一个http客户端,它就是用来发送http请求的,但是Ribbon在httpclient上做了更多的封装,满足更好的使用,当然,也可以使用其他的http客户端。所以,Ribbon并不是很多人说的负载均衡工具,而是一个具有负载均衡等功能的http客户端。

Ribbon基本须知配置

(1)IClientConfig clientConfig:用于配置负载均衡客户端,默认实现类是DefaultClientConfigImpl。

(2)IRule rule:用于配置负载均衡的策略,默认使用的是RoundRobinRule策略,也就是轮询策略。

(3)IPing ping:用于检查当前服务是否有响应,从而判断当前服务是否可用,默认实现类是DummyPing,该实现类的isAlive()方法返回值是true,默认所有服务实例都是可用的。

(4)ServerList serverList: 用于获取所有Server注册列表信息。通过跟踪源码会发现,ServerList的实现类是DiscoveryEnabledNIWSServerList,该类定义的obtainServersViaDiscovery()方法是根据eurekaClientProvider.get()方法获取EurekaClient,再根据EurekaClient获取服务注册列表信息。EurekaClient的实现类是DiscoveryClient,DiscoveryClient具有服务注册、获取服务注册列表等功能。

(5)ServerListFilter filter:定义了根据配置过滤或者动态获取符合条件的服务列表,默认实现类是ZonePreferenceServerListFilter,该策略能够优先过滤出与请求调用方处于同区域的服务实例。

ribbon基本配置

1. 禁用 Eureka

当我们在 RestTemplate 上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。

这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,如果我们不想和 Eureka 集成,可以通过下面的配置方法将其禁用。

# 禁用 Eureka
ribbon.eureka.enabled=false

当我们禁用了 Eureka 之后,就不能使用服务名称去调用接口了,必须指定服务地址。

2. 配置接口地址列表

上面我们讲了可以禁用 Eureka,禁用之后就需要手动配置调用的服务地址了,配置如下:

# 禁用 Eureka 后手动配置服务地址
ribbon-config-demo.ribbon.listOfServers=localhost:8081,localhost:8083

这个配置是针对具体服务的,前缀就是服务名称,配置完之后就可以和之前一样使用服务名称来调用接口了。

3. 配置负载均衡策略

Ribbon 默认的策略是轮询,从我们前面讲解的例子输出的结果就可以看出来,Ribbon 中提供了很多的策略,这个在后面会进行讲解。我们通过配置可以指定服务使用哪种策略来进行负载操作。

4. 超时时间

Ribbon 中有两种和时间相关的设置,分别是请求连接的超时时间和请求处理的超时时间,设置规则如下:

# 请求连接的超时时间
ribbon.ConnectTimeout=2000
# 请求处理的超时时间
ribbon.ReadTimeout=5000

#也可以为每个Ribbon客户端设置不同的超时时间, 通过服务名称进行指定:
ribbon-config-demo.ribbon.ConnectTimeout=2000
ribbon-config-demo.ribbon.ReadTimeout=5000

5. 并发参数

# 最大连接数
ribbon.MaxTotalConnections=500
# 每个host最大连接数
ribbon.MaxConnectionsPerHost=500

代码配置 Ribbon

配置 Ribbon 最简单的方式就是通过配置文件实现。当然我们也可以通过代码的方式来配置。

通过代码方式来配置之前自定义的负载策略,首先需要创建一个配置类,初始化自定义的策略,代码如下所示。

@Configurationpublic class BeanConfiguration {    @Bean    public MyRule rule() {        return new MyRule();    }}

创建一个 Ribbon 客户端的配置类,关联 BeanConfiguration,用 name 来指定调用的服务名称,代码如下所示。

纯文本复制
@RibbonClient(name = "ribbon-config-demo", configuration = BeanConfiguration.class)public class RibbonClientConfig {}

重试机制

在集群环境中,用多个节点来提供服务,难免会有某个节点出现故障。用 Nginx 做负载均衡的时候,如果你的应用是无状态的、可以滚动发布的,也就是需要一台台去重启应用,这样对用户的影响其实是比较小的,因为 Nginx 在转发请求失败后会重新将该请求转发到别的实例上去。

由于 Eureka 是基于 AP 原则构建的,牺牲了数据的一致性,每个 Eureka 服务都会保存注册的服务信息,当注册的客户端与 Eureka 的心跳无法保持时,有可能是网络原因,也有可能是服务挂掉了。

在这种情况下,Eureka 中还会在一段时间内保存注册信息。这个时候客户端就有可能拿到已经挂掉了的服务信息,故 Ribbon 就有可能拿到已经失效了的服务信息,这样就会导致发生失败的请求。

这种问题我们可以利用重试机制来避免。重试机制就是当 Ribbon 发现请求的服务不可到达时,重新请求另外的服务。

1. RetryRule 重试

解决上述问题,最简单的方法就是利用 Ribbon 自带的重试策略进行重试,此时只需要指定某个服务的负载策略为重试策略即可:

ribbon-config-demo.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RetryRule

2. Spring Retry 重试

除了使用 Ribbon 自带的重试策略,我们还可以通过集成 Spring Retry 来进行重试操作。

在 pom.xml 中添加 Spring Retry 的依赖,代码如下所示。

<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
</dependency>

配置重试次数等信息:

# 对当前实例的重试次数
ribbon.maxAutoRetries=1
# 切换实例的重试次数
ribbon.maxAutoRetriesNextServer=3
# 对所有操作请求都进行重试
ribbon.okToRetryOnAllOperations=true
# 对Http响应码进行重试
ribbon.retryableStatusCodes=500,404,502

Feign

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。

Feign能干什么

Feign旨在是编写Java Http客户端变得更加容易。

  • Feign 是声明式的web service客户端,它让微服务之间的调用变得更加简单了
  • SpringCloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端
  • 使用起来也比ribbon方便很多,只需要创建接口,然后使用注解@FeignClient("服务名")即可

Feign的用途

  • 因为在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用,Feign在此基础上进行了进一步的封装,由他来帮助我们定义和实现依赖服务接口的定义
  • 在Feign的是线下,我们只需要创建一个接口并使用注解的方式来装配它@FeignClient("服务名"),即可完成对服务提供方的接口绑定,简化了Ribbon自动封装服务调用客户端的开发量

Feign与Ribbon的关系

  • Feign集成了Ribbon
  • Feign利用了Ribbon维护了服务列表信息,并且通过轮询的方式实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,更加简单的实现了服务的调用

Feign实现远程调用流程图:

在这里插入图片描述

Feign解决什么问题

Feign旨在是编写java http客户端变得更加容易,Feign简化了RestTemplate代码,实现了Ribbon负载均衡,使代码变得更加简洁,也少了客户端调用的代码,使用Feign实现负载均衡是首先方案。只需要你创建一个接口,然后在上面添加注解即可。
Feign是声明式服务调用组件,其核心就是:像调用本地方法一样调用远程方法,无感知远程HTTP请求。

  • 它解决了让开发者调用远程接口就跟调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是HTTP请求。无需关注与远程的交互细节,更无需关注分布式环境开发。

  • 它像Dubbo一样,Consumer直接调用Provider接口方法,而不需要通过常规的Http Client构造请求再解析返回数据。

    Feign vs OpenFeign

  • OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如果@RequstMapping、@Pathvariable等等。

  • OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实效类,实效类中做负载均衡并调用服务。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM