服务调用 |
---|
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 | "stores") (value = |
其中@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 | "${feign.name}", url = "${feign.url}") (name = |
Spring Cloud Netflix默认为feign提供了以下Bean (BeanType
的bean名称: ClassName
):
Decoder
feignDecoder:ResponseEntityDecoder
(which wraps aSpringDecoder
)Encoder
feignEncoder:SpringEncoder
Logger
feignLogger:Slf4jLogger
Contract
feignContract:SpringMvcContract
Feign.Builder
feignBuilder:HystrixFeign.Builder
Client
feignClient: 如果类包含了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.Level
Retryer
ErrorDecoder
Request.Options
Collection<RequestInterceptor>
SetterFactory
QueryMapEncoder
默认情况下,会创建一个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 | "fooClient", name = "stores", configuration = FooConfiguration.class) (contextId = |
三 手动创建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 | "hello", fallback = HystrixClientFallback.class) (name = |
如果需要访问引起回退触发器的原因,则可以使用@FeignClient中的fallbackFactory属性。
1 | "hello", fallbackFactory = HystrixClientFallbackFactory.class) (name = |
六 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。