Spring Cloud OpenFeign
- 一、Ribbon是什么?
- 1、客户端负载均衡 vs 服务端负载均衡
- 2、采用Ribbon实现服务调用
- 3、 Ribbon 负载均衡策略
- 二、Spring Cloud OpenFeign
- 1、Feign是什么?
- 2、 Feign能干什么?
- 3、使用Feign实现消费者
- 4、使用Feign实现消费者的测试
- 5、OpenFegin的所有配置
一、Ribbon是什么?
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡器;
我们通常说的负载均衡是指将一个请求均匀地分摊到不同的节点单元上执行,负
载均和分为硬件负载均衡和软件负载均衡:
硬件负载均衡:比如 F5、深信服、Array 等;
软件负载均衡:比如 Nginx、LVS、HAProxy 等;(是一个服务器实现的)
Ribbon是Netflix公司发布的开源项目(组件、框架、jar包),主要功能是提供客户端的软件负载均衡算法,它会从eureka中获取一个可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点。
当客户端发送请求,则ribbon负载均衡器按某种算法(比如轮询、权重、 最小连接数等)从维护的可用服务端清单中取出一台服务端的地址,然后进行请求;
Ribbon非常简单,可以说就是一个jar包,这个jar包实现了负载均衡算法,Spring Cloud 对 Ribbon 做了二次封装,可以让我们使用 RestTemplate 的服务请求,自动转换成客户端负载均衡的服务调用。
Ribbon 支持多种负载均衡算法,还支持自定义的负载均衡算法。
1、客户端负载均衡 vs 服务端负载均衡
2、采用Ribbon实现服务调用
- 1、首先加入ribbon的依赖,但是eureka已经依赖了ribbon,所以这里不需要再引用ribbon的依赖;
- 2、要使用ribbon,只需要一个注解:
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
在RestTemplate上面加入@LoadBalanced注解,这样就可以实现RestTemplate 在调用时自动负载均衡;
我们可以启动了eureka集群(3个eureka) 和服务提供者集群(2个service-goods) 和一个服务调用者(service-portal)
#告诉服务端,服务实例的唯一ID
eureka.instance.instance-id=springcloud-service-portal
3、 Ribbon 负载均衡策略
Ribbon 的负载均衡策略是由 IRule 接口定义, 该接口由如下实现:
在jar包:com.netflix.ribbon#ribbon-loadbalancer中
要使用ribbon实现负载均衡,在Spring 的配置类里面把对应的负载均衡接口实现类作为一个Bean配置一下就行了;
负载均衡的入口:ILoadBalancer接口
如果要切换负载均衡策略:
@Bean
public IRule iRule(){
return new RoundRobinRule();
}
负载均衡实现 | 策略 |
RandomRule | 随机 |
RoundRobinRule | 轮询 |
AvailabilityFilteringRule | 先过滤掉由于多次访问故障的服务,以及并 发连接数超过阈值的服务,然后对剩下的服 务按照轮询策略进行访问 |
WeightedResponseTimeRule | 根据平均响应时间计算所有服务的权重,响 应时间越快服务权重就越大被选中的概率即 越高,如果服务刚启动时统计信息不足,则 使用RoundRobinRule策略,待统计信息足够会切换到该WeightedResponseTimeRule策 略; |
RetryRule | 先按照RoundRobinRule策略分发,如果分发 到的服务不能访问,则在指定时间内进行重试,然后分发其他可用的服务; |
BestAvailableRule | 先过滤掉由于多次访问故障的服务,然后选 择一个并发量最小的服务; |
ZoneAvoidanceRule (默认) | 综合判断服务节点所在区域的性能和服务节 点的可用性,来决定选择哪个服务; |
二、Spring Cloud OpenFeign
文档地址:[https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign]
1、Feign是什么?
Feign 是 Netflix 公司开发的一个声明式的 REST 调用客户端; (调用远程的restful风格的http接口 的一个组件)
调用组件其实很多,比如:
-1、Httpclient(apache)
-2、Httpurlconnection (jdk)
-3、restTemplate(spring)
-4、OkHttp(android)
-5、Feign (Netflix) --> 实现非常优雅
Spring Cloud OpenFeign对 Ribbon 负载均衡进行了简化,在其基础上进行了进一步的封装,在配置上大大简化了开发工作,它是一种声明式的调用方式,它的使用方法是定义一个接口,然后在接口上添加注解,使其支持了Spring MVC标准注解和HttpMessageConverters,Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
2、 Feign能干什么?
Feign旨在简化微服务消费方(调用者,客户端)代码的开发,前面在使用Ribbon+RestTemplate进行服务调用时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方式,但是在实际开发中,由于服务提供者提供的接口非常多,一个接口也可能会被多处调用,Feign在Ribbon+RestTemplate的基础上做了进一步封装,在Feign封装之后,我们只需创建一个接口并使用注解的方式来配置,即可完成对服务提供方的接口绑定,简化了使用Ribbon + RestTemplate的调用,自动封装服务调用客户端,减少代码开发量;
3、使用Feign实现消费者
使用 Feign 实现消费者,我们通过下面步骤进行:
- 第一步:创建普通 Spring Boot 工程
把接口放在通用的接口层、常量类、model的项目中 - 第二步:添加依赖
<!-- spring-cloud-starter-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 第三步:声明服务
定义一个 GoodsRemoteClient 接口,通过@FeignClient 注解来指定服务名称,进而绑定服务,然后再通过 SpringMVC 中提供的注解来绑定服务提供者提供的接口, 如下:
@FeignClient("SPRINGCLOUD-SERVICE-GOODS")
public interface GoodsService {
@RequestMapping("/service/goods")
public String goods();
}
这相当于绑定了一个springcloud-service-goods (大小写都可以 ) 的服务提供者提供的/service/goods 接口;
- 第四步:添加注解
在项目入口类上添加@EnableFeignClients 注解表示开启 Spring Cloud Feign的支持功能;
第五步:使用 Controller 中调用服务
/**
*接着来创建一个 Controller 来调用上面的服务,如下:
*/
public class GoodsController {
@Autowired
private GoodsService goodsService;
/**
* 使用feign进行调用
*
* @return
*/
@RequestMapping("/cloud/goodsFeign")
public ResultObject goodsFeign() {
//调用远程的一个controller, restful的调用
return goodsService.goods();
}
}
- 第六步:属性配置
在 application.properties 中指定服务注册中心、端口号等信息,如下:
server.port=8090
#打开所有的web访问端点
management.endpoints.web.exposure.include=*
#此实例注册到eureka服务端的name
spring.application.name=springcloud-service-feign
#不注册自己,我是一个消费者,别人如果不调用我的话,我就不用注册
eureka.client.register-with-eureka=false
#每间隔2s,向服务端发送一次心跳,证明自己依然"存活"
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果我10s之内没有给你发心跳,就代表我故障了,将我踢出掉
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,而不是取机器名
eureka.instance.prefer-ip-address=true
#告诉服务端,服务实例的唯一ID
eureka.instance.instance-id=springcloud-service-feign
#eureka注册中心的连接地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka
- 第七步:测试
依次启动注册中心、服务提供者和 feign 实现服务消费者,然后访问如下地址:
http://localhost:8090/cloud/goodsFeign
4、使用Feign实现消费者的测试
我们可以多启动几个提供者就可以进行测试了
负载均衡:
我们知道,Spring Cloud 提供了 Ribbon 来实现负载均衡,使用 Ribbo 直接注入一个 RestTemplate 对象即可,RestTemplate 已经做好了负载均衡的配置;
在 Spring Cloud 下,使用 Feign 也是直接可以实现负载均衡的,定义一个有@FeignClient 注解的接口,然后使用@RequestMapping 注解到方法上映射远程的 REST 服务,此方法也是做好负载均衡配置的;
通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用;
5、OpenFegin的所有配置
文档地址:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign
配置 | 默认 | 描述 |
feign.autoconfiguration.jackson.enabled |
| 如果为真,将为杰克逊页面解码提供 PageJacksonModule 和 SortJacksonModule bean。 |
feign.circuitbreaker.alphanumeric-ids.enabled |
| 如果为 true,断路器 ID 将仅包含字母数字字符,以允许通过配置属性进行配置。 |
feign.circuitbreaker.enabled |
| 如果为 true,OpenFeign 客户端将被 Spring Cloud CircuitBreaker 断路器包裹。 |
feign.circuitbreaker.group.enabled |
| 如果为 true,OpenFeign 客户端将使用带有组的 Spring Cloud CircuitBreaker 断路器进行包装。 |
feign.client.config | ||
feign.client.decode-斜线 |
| Feign 客户端默认不编码斜线 |
feign.client.default-config |
| |
feign.client.default-to-properties |
| |
feign.client.refresh-enabled |
| 为 Feign 启用选项值刷新功能。 |
feign.compression.request.enabled |
| 允许对 Feign 发送的请求进行压缩。 |
feign.compression.request.mime 类型 |
| 支持的 mime 类型列表。 |
feign.compression.request.min-request-size |
| 最小阈值内容大小。 |
feign.compression.response.enabled |
| 使来自 Feign 的响应能够被压缩。 |
feign.encoder.charset-from-content-type |
| 指示字符集是否应从 {@code Content-Type} 标头派生。 |
feign.httpclient.connection-timeout |
| |
feign.httpclient.connection-timer-repeat |
| |
feign.httpclient.disable-ssl-validation |
| |
feign.httpclient.enabled |
| 允许 Feign 使用 Apache HTTP 客户端。 |
feign.httpclient.follow-redirects |
| |
feign.httpclient.hc5.enabled |
| 允许 Feign 使用 Apache HTTP Client 5。 |
feign.httpclient.hc5.pool-concurrency-policy | 池并发策略。 | |
feign.httpclient.hc5.pool-reuse-policy | 池连接重用策略。 | |
feign.httpclient.hc5.socket-timeout |
| 套接字超时的默认值。 |
feign.httpclient.hc5.socket-timeout-unit | 套接字超时单位的默认值。 | |
feign.httpclient.max-connections |
| |
feign.httpclient.max-connections-per-route |
| |
feign.httpclient.ok-http.read-timeout |
| {@link OkHttpClient} 读取超时;默认为 60 秒。 |
feign.httpclient.time-to-live |
| |
feign.httpclient.time-to-live-unit | ||
feign.metrics.enabled |
| 为 Feign 启用指标功能。 |
feign.oauth2.enabled |
| 启用 feign 拦截器以管理 oauth2 访问令牌。 |
feign.oauth2.load-balanced |
| 为 oauth2 访问令牌提供程序启用负载平衡。 |
feign.okhttp.enabled |
| 允许 Feign 使用 OK HTTP 客户端。 |