Spring Cloud 之 OpenFeign
1、Feign 简介
Spring Cloud OpenFeign是一套基于Netflix Feign实现的声明式、模板化的服务调用客户端,Feign可以帮助我们更快捷、优雅地调用HTTP API,它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
2、简单使用
在前面学习《Eureka注册中心》和《客户端负载均衡》中,我们一直使用了RestTemplate进行服务接口的调用,这个时候我们需要知道服务接口的具体信息,比如:IP地址或服务名、端口号、接口地址等,这种使用近似原始Http方式的调动,为我们编写代码带来了很大的复杂度。而Feign就是封装了这些细节,为我们提供了更加快捷和优雅的调用HTTP API的方法,我们下面拭目以待:
1、构建基于Feign的消费者客户端
注册中心和服务提供者可以使用前面例子中的应用,这里只需要重构消费者引用即可,因为Feign本身就是为了简化开发者编写消费服务接口的HTTP封装。
2、引入Feign依赖
在原来的消费基础上,增加Feign相关依赖即可,如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
3、开启Feign功能
开启Feign功能很简单,只需要在启动类中添加@EnableFeignClients注解接口,这样就启动了Feign功能。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EurekaConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class, args);
}
}
4、定义Feign接口
定义Feign接口是实现Feign调用非常重要和基础的工作,Feign就是根据定义的接口和其中的注解实现了服务接口的调用,同时当前应用只需要像本地类一样调用对应的方法即可。
@FeignClient("eureka-provider")
public interface FeignApiClient {
@GetMapping("/provider")
String provider();
}
在上述代码中,@FeignClient注解作用目标在接口上,用来表示该接口作为一个FeignClient使用,其中的value,表示FeignClient的名称(如果使用了服务注册中心,一般使用服务提供者的名称),如果项目使用了Ribbon,value属性会作为微服务的名称,用于服务发现。而@GetMapping注解,主要用来指定在对应的服务提供者中的HTTP API,即该方法被调用时,实际调用服务提供者的地址。
5、编写消费者Controller
这里只需要一个定义一个普通的Controller类即可,其中需要把前面定义的Feign接口类FeignApiClient注入到该类中即可,这个时候,我们就可以像使用普通的service类一样,调用该接口的指定方法了。
@RestController
public class FeignController {
Logger logger = Logger.getLogger(FeignController.class);
@Autowired
private FeignApiClient feignApiClient;
@RequestMapping("/feignApi")
public String feignApi(){
logger.info("执行消费者FeignController的feignApi()方法!");
return feignApiClient.provider();
}
}
6、启动、验证
启动应用,正常启动后,访问http://localhost:8020/feignApi,这个时候,服务提供者的接口就被正常调用了,消费者也返回了正确的信息。这个时候,Feign的简单实例我们就完成了,这里我们只是简单了构建了一个基于Feign的消费者,我们下面再尝试一些其他的用法。
3、 Feign日志级别
3.1、单个服务的日志配置
启用Feign日志配置需要两步:
第一步,在配置文件application.properties中增加相关配置:
# 启用Feign日志级别
logging.level.com.qriver.cloud.consumer.feign.FeignApiClient: DEBUG
其中,logging.level是固定前缀,com.qriver.cloud.consumer.feign.FeignApiClient是对应的Feign接口的权限定类名,对应的Value值只能是DEBUG类型。
第二步,增加Feign日志的配置类或增加相应配置。
如果使用配置文件形式,在配置文件application.properties中增加下面配置即可,其中feign.client.config是固定格式,eureka-provider是服务提供者的应用名称,logger-level固定格式,full是选用的日志级别。
feign.client.config.eureka-provider.logger-level: full
如果选择增加Feign日志的配置类的方式,代码如下:
@Configuration
public class FeignLoggingConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
在上述配置类中,我们使用了FULL级别的日志,无论使用配置文件还是配置类的方式,这种都是针对每一个微服务的服务提供者进行配置的。
3.2、全局日志配置
Feign日志进行全局配置时,也是需要两步:
第一步,定义需要输出日志的地方,这个和java web中普通日志方式是一样的,即配置需要打印日志的包配置。
# 启用Feign日志级别
logging.level.com.qriver.cloud.consumer.feign.*: DEBUG
第二步,增加Feign全局日志配置,和单个服务配置类似,也有配置类和配置文件两种方式。
如果使用配置文件方式,只需要在配置文件中增加如下配置即可:
feign.client.config.default.logger-level: full
和单个服务提供者日志配置相比,这里把服务名称改成default即可。
如果选择使用配置类,配置类的定义方法和前面为单个服务定义的配置类是一样的。只需要把@Configuration注解移除就可以了,这里不再重复贴出。全局日志配置的引入方式,需要修改启用Feign的注解@EnableFeignClients,增加defaultConfiguration属性,并把配置类引入即可,代码如下:
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(defaultConfiguration = FeignLoggingConfig.class)
public class EurekaConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class, args);
}
}
3.3、Feign日志级别
Feign一共有四种级别的日志,分别是:
- NONE: 不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL及响应状态和执行时间,类似于Tomcat默认的访问日志。
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
- FULL:记录了所有请求和响应的明细,包括头信息、请求体和元数据等。
下面贴出来四种不同级别,打印的日志示例:
FULL级别:
2020-11-08 14:53:07.697 INFO 2504 --- [nio-8020-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@66e383de
2020-11-08 14:53:07.830 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] <--- HTTP/1.1 200 (490ms)
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] connection: keep-alive
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] content-length: 12
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] content-type: text/plain;charset=UTF-8
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] date: Sun, 08 Nov 2020 06:53:07 GMT
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] keep-alive: timeout=60
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider]
2020-11-08 14:53:07.833 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] Hello World!
2020-11-08 14:53:07.834 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] <--- END HTTP (12-byte body)
2020-11-08 14:53:08.661 INFO 2504 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
HEADERS级别:
2020-11-08 14:55:45.091 INFO 10800 --- [nio-8020-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@7e8dcbf2
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] <--- HTTP/1.1 200 (375ms)
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] connection: keep-alive
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] content-length: 12
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] content-type: text/plain;charset=UTF-8
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] date: Sun, 08 Nov 2020 06:55:45 GMT
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] keep-alive: timeout=60
2020-11-08 14:55:45.180 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] <--- END HTTP (12-byte body)
2020-11-08 14:55:46.061 INFO 10800 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
BASIC级别:
2020-11-08 14:59:01.149 INFO 94780 --- [nio-8020-exec-2] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@23aa7540
2020-11-08 14:59:01.239 DEBUG 94780 --- [nio-8020-exec-2] c.q.cloud.consumer.feign.FeignApiClient : [FeignApiClient#provider] <--- HTTP/1.1 200 (393ms)
2020-11-08 14:59:02.117 INFO 94780 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
NONE级别:
2020-11-08 15:00:40.790 INFO 44616 --- [nio-8020-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@739c9f13
2020-11-08 15:00:41.759 INFO 44616 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
4、压缩请求和响应数据
为了提高请求数据和响应数据在网络中的传输效率,Feign提供了对请求和响应的数据的压缩功能。开启方式如下:
feign.compression.request.enabled=true
feign.compression.response.enabled=true
那些请求或响应可以被压缩?Feign提供了两种策略,第一种是根据多媒体类型,第二种是根据请求的大小,具体配置如下:
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
5、基于Ribbon的负载均衡
Feign实现基于Ribbon的负载均衡非常容易。首先,需要引入Ribbon的依赖文件,如下所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
然后,在定义Feign接口的时候,@FeignClient注解name或value属性使用服务名称(不绑定具体实例地址即可)即可。
5.1、准备环境
验证所需的环境和《客户端负载均衡》中所需的环境一样,然后重构消费者就可以了,而且消费者只需要引入ribbon依赖,Feign就会自动的启用负载均衡机制。
5.2、验证
启动后,通过多次访问接口,就会发现服务提供者均匀的分别到了两个服务上,说明负载均衡生效了。这里只是简单的实现了负载均衡,我们后面再详细分析他们是如何进行工作的。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/68775.html