| 服务调用 |
|---|
| 01 服务调用Dubbo之快速上手 |
| 02 服务调用Feign之快速上手 |
| 03 服务调用Feign之SpringCloudOpenFeign |
| 04 服务调用Feign之配置 |
一 如何引入Feign
需要引入依赖group: org.springframework.cloud artifact id: spring-cloud-starter-openfeign
并且使用注解@EnableFeignClients使Feign生效
1 |
|
定义Feign接口
1 | (value = "stores") |
其中@FeignClient中的属性value一般是用于创建一个Ribbon load-balancer (see below for details of Ribbon support) 或者 Spring Cloud LoadBalancer,在微服务中,该正常是服务的名称,即spring.application.name,也可以使用url属性(绝对值或仅是主机名)指定URL。
二 覆盖Feign客户端默认配置
Spring Cloud的Feign支持的中心概念是指定客户的概念。每个Feign客户端都是组件的一部分,这些组件可以一起工作以按需联系远程服务器,并且该组件的名称是您使用@FeignClient注解作为应用程序开发人员提供的。 Spring Cloud使用FeignClientsConfiguration根据需要为每个命名客户端创建一个新的集成作为ApplicationContext。其中包含一个feign.Decoder,一个feign.Encoder和一个feign.Contract。通过使用@FeignClient注解的contextId属性,可以覆盖该集合的名称。
Spring Cloud通过使用@FeignClient声明其他配置(在FeignClientsConfiguration之上),使您可以完全控制feign客户端。例:
@FeignClient中的属性可以通过占位符替换如:
1 | (name = "${feign.name}", url = "${feign.url}") |
Spring Cloud Netflix默认为feign提供了以下Bean (BeanType 的bean名称: ClassName):
DecoderfeignDecoder:ResponseEntityDecoder(which wraps aSpringDecoder)EncoderfeignEncoder:SpringEncoderLoggerfeignLogger:Slf4jLoggerContractfeignContract:SpringMvcContractFeign.BuilderfeignBuilder:HystrixFeign.BuilderClientfeignClient: 如果类包含了Ribbon并且ribbon启用了则使用LoadBalancerFeignClient, 否则如果类包含了Spring Cloud LoadBalancer则使用FeignBlockingLoadBalancerClient. 如果在类中以上两个依赖都没有, 则使用默认的feign client.
spring-cloud-starter-openfeign支持spring-cloud-starter-netflix-ribbon和spring-cloud-starter-loadbalancer. 然后, 由于它们都是可选依赖, 需要确保要使用的那个已添加到您的项目中.
可以通过将feign.okhttp.enabled或feign.httpclient.enabled分别设置为true并将它们放在类路径中来使用OkHttpClient和ApacheHttpClient feign客户端。您可以通过使用Apache时提供org.apache.http.impl.client.CloseableHttpClient的bean或使用OK HTTP时提供okhttp3.OkHttpClient的bean来定制HTTP客户端。
默认情况下,Spring Cloud OpenFeign不会为Feign提供以下bean,但仍会从应用程序上下文中查找这些类型的bean以创建Feign客户端:
Logger.LevelRetryerErrorDecoderRequest.OptionsCollection<RequestInterceptor>SetterFactoryQueryMapEncoder
默认情况下,会创建一个Retryer.NEVER_RETRY类型为Retryer的bean,它将禁用重试。请注意,此重试行为不同于Feign的默认行为,在Feign默认行为中,它将自动重试IOException,将它们视为与网络临时相关的异常,以及从ErrorDecoder抛出的任何RetryableException。
@FeignClient也可以使用配置属性进行配置,如下:
1 | feign: |
可以使用与上述类似的方式在@EnableFeignClients属性defaultConfiguration中指定默认配置。不同之处在于此配置将适用于所有伪客户端。
如果您希望使用配置属性来配置所有@FeignClient,则可以使用默认伪名称创建配置属性。
1 | feign: |
如果我们同时创建@Configuration bean和configuration属性,则配置属性将获胜。它将覆盖@Configuration值。但是,如果要将优先级更改为@Configuration,可以将feign.client.default-to-properties更改为false。
注意:如果需要在RequestInterceptor中使用
ThreadLocal绑定变量,则需要将Hystrix的线程隔离策略设置为SEMAPHORE或在Feign中禁用Hystrix。
1 | # To disable Hystrix in Feign |
如果我们要创建多个具有相同名称或URL的虚拟客户端,以便它们指向同一台服务器,但每个客户端使用不同的自定义配置,则必须使用@FeignClient的contextId属性,以避免这些配置的名称冲突bean。
1 | (contextId = "fooClient", name = "stores", configuration = FooConfiguration.class) |
三 手动创建Feign客户端
在某些情况下,可能有必要使用上述方法无法实现的方式自定义Feign客户。在这种情况下,您可以使用Feign Builder API创建客户端。下面是一个示例,该示例创建具有相同接口的两个Feign Client,但为每个Feign Client配置一个单独的请求拦截器。
1 | (FeignClientsConfiguration.class) |
在上面的示例中,FeignClientsConfiguration.class是Spring Cloud Netflix提供的默认配置。
四 Feign Hystrix支持
如果Hystrix在类路径上并且
feign.hystrix.enabled=true,则Feign将使用断路器包装所有方法。还可以返回com.netflix.hystrix.HystrixCommand。这使您可以使用反应性模式(通过调用.toObservable()或.observe()或异步使用(通过调用.queue())。
要基于每个客户端禁用Hystrix支持,请创建具有“prototype”范围的Feign.Builder,例如:
1 |
|
在Spring Cloud Dalston发行版之前,如果Hystrix在类路径中,则Feign默认会将所有方法包装在断路器中。 Spring Cloud Dalston中更改了此默认行为,以支持选择加入方法。
五 Feign Hystrix Fallbacks
Hystrix支持fallback的概念:当它们的电路断开或出现错误时执行的默认代码路径。要为给定的
@FeignClient启用fallback,请将fallback属性设置为实现回退的类名称。您还需要将实现声明为Spring bean。
1 | (name = "hello", fallback = HystrixClientFallback.class) |
如果需要访问引起回退触发器的原因,则可以使用@FeignClient中的fallbackFactory属性。
1 | (name = "hello", fallbackFactory = HystrixClientFallbackFactory.class) |
六 Feign继承支持
Feign通过单继承接口支持样板API。这允许将常用操作分组为方便的基本接口。
UserService.java
1 | public interface UserService { |
UserResource.java
1 |
|
UserClient.java
1 | package project.user; |
通常不建议在服务器和客户端之间共享接口。它引入了紧密耦合,并且实际上也无法以当前形式与Spring MVC配合使用(方法参数映射不被继承)。
七 Feign请求/响应压缩
您可以考虑为您的Feign请求启用请求或响应GZIP压缩。您可以通过启用以下属性之一来做到这一点:
1 | feign.compression.request.enabled=true |
Feign请求压缩为您提供的设置类似于您为Web服务器设置的设置:
1 | feign.compression.request.enabled=true |
这些属性使您可以选择压缩媒体类型和最小请求阈值长度。
对于OkHttpClient以外的http客户端,可以启用默认的gzip解码器以UTF-8编码解码gzip响应:
1 | feign.compression.response.enabled=true |
八 Feign日志
为每个创建的Feign客户端创建一个记录器。默认情况下,记录器的名称是用于创建Feign客户端的接口的全类名称。Feign日志仅响应DEBUG级别。
1 | logging.level.project.user.UserClient: DEBUG |
您可以为每个客户端配置的
Logger.Level对象告诉Feign要记录多少。选择是:
NONE, No logging (DEFAULT).BASIC, Log only the request method and URL and the response status code and execution time.HEADERS, Log the basic information along with request and response headers.FULL, Log the headers, body, and metadata for both requests and responses.
例如,以下将把Logger.Level设置为FULL:
1 |
|
九 Feign QueryMap支持
OpenFeign
@QueryMap注解支持将POJO用作GET参数映射。不幸的是,默认的OpenFeign QueryMap注释与Spring不兼容,因为它缺少value属性。Spring Cloud OpenFeign提供等效的
@SpringQueryMap注解,该注解用于将POJO或Map参数注释为查询参数映射。例如,
Params类定义参数param1和param2:
1 | // Params.java |
以下Feign客户端通过使用
@SpringQueryMap注解来使用Params类:
1 | ("demo") |
如果需要对生成的查询参数映射进行更多控制,则可以实现自定义QueryMapEncoder Bean。
