Finchley.SR2
## First, what is Feign
feign web client is a declarative, you can use it in the comments to create an interface, it also supports custom codecs. Spring Cloud integrates Ribbon and Eureka provides clients with a load balancing policy. There are two main Feing Notes: (@EnableFeignClients for opening feign function, @ FeignClient used to define feign Interface).
## Second, the introduction of Feign
1, increased reliance
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
复制代码
2、Example spring boot app
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
复制代码
StoreClient.java
@FeignClient("stores")
public interface StoreClient {
@RequestMapping(method = RequestMethod.GET, value = "/stores")
List<Store> getStores();
@RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
Store update(@PathVariable("storeId") Long storeId, Store store);
}
复制代码
In this @FeignClient annotation ( "stores") argument is a unique name (in fact, this is the general service name) for creating Ribbon load balancer. It can also be used on its annotation url parameters (parameter is the absolute path to find, such as www.xxx.com). . This Ribbon) This Ribbon client will find the physical address in accordance with ( "stores"), if it is used Eureka will find services in their registry, if not used can also configure an external list.
## Third, the default properties covering Feign
feign components as long as @FeignClient statement is a client, we can create our custom configuration items by using FeignClientsConfiguration, for example feign.Decoder
, A feign.Encoder
, A and feign.Contract.
Example
@FeignClient(name = "stores", configuration = FooConfiguration.class)
public interface StoreClient {
//..
}
复制代码
In this demo client by the combination of the two and FooConfiguration FeignClientsConfiguration formed (disposed behind the override earlier)
FooConfiguration @Configuration not need this type of comment. If you need to add this to exclude when using @ComponentScan scan. Otherwise, this stuff will become feign.Decoder
, feign.Encoder
, feign.Contract 的默认配置了。
@FeignClient 中 serviceId 属性已经废弃了,请注意。
在以前@FeignClient 中使用url时不需要配置name属性,现在这版本必须配置。
A placeholder on @FeignClient the url attribute and name
@FeignClient(name = "${feign.name}", url = "${feign.url}")
public interface StoreClient {
//..
}
复制代码
Spring Cloud provides several default class for Feign
Decoder
feignDecoder:ResponseEntityDecoder
(which wraps aSpringDecoder
)Encoder
feignEncoder:SpringEncoder
Logger
feignLogger:Slf4jLogger
Contract
feignContract:SpringMvcContract
Feign.Builder
feignBuilder:HystrixFeign.Builder
Client
feignClient: If the Ribbon is turned onLoadBalancerFeignClient
, do not open, then you use the default.
The following class is not available by default, but in time will create a client to find the load, use some words
Logger.Level
Retryer
ErrorDecoder
Request.Options
Collection<RequestInterceptor>
SetterFactory
Just like the top of the demo, create a class using @FeignClient configure its configuration (such as is this FooConfiguration), Example
@Configuration
public class FooConfiguration {
@Bean
public Contract feignContract() {
return new feign.Contract.Default();
}
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("user", "password");
}
}
复制代码
The above configuration is to replace SpringMvcContract feign.Contract.Default, and adds an interceptor. Of course, also possible to use a profile configured @FeignClient follows:
application.yml
eign:
client:
config:
feignName:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: full
errorDecoder: com.example.SimpleErrorDecoder
retryer: com.example.SimpleRetryer
requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
decode404: false
encoder: com.example.SimpleEncoder
decoder: com.example.SimpleDecoder
contract: com.example.SimpleContract
复制代码
Of course, this configuration class can be placed inside @EnableFeignClients property, but such a configuration is so, then the client will take effect. If you want to configure all @FeignClient, you can use the default name feign default as follows:
application.yml
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: basic
复制代码
If we create a configuration file that is created and configured class, and that the highest priority of the configuration file will overwrite the configuration attributes of the class. May be used feign.client.default-to-properties = false to change this characteristic.
If you need to use ThreadLocal binding parameters, you need to set Hystrix isolation as SEMAPHORE
# To disable Hystrix in Feign
feign:
hystrix:
enabled: false
# To set thread isolation to SEMAPHORE
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
复制代码
## Fourth, manually create Feign client
In some cases the above configuration does not meet your client, you would need to use Feign Builder API . Manually create a client. When you create can use different interceptors.
@Import(FeignClientsConfiguration.class)
class FooController {
private FooClient fooClient;
private FooClient adminClient;
@Autowired
public FooController(Decoder decoder, Encoder encoder, Client client, Contract contract) {
this.fooClient = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
.target(FooClient.class, "http://PROD-SVC");
this.adminClient = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(FooClient.class, "http://PROD-SVC");
}
}
复制代码
FeignClientsConfiguration cloud is the default configuration class, PROD-SVC is the service name. Contract is injected with a default.
## five, Feign Hystrix Fallbacks (downgrade)
Downgrade concept: When code execution failure or downgrade policy is turned on, you can set a fallback property demotion to achieve this strategy @FeignClient.
@FeignClient(name = "hello", fallback = HystrixClientFallback.class)
protected interface HystrixClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello iFailSometimes();
}
static class HystrixClientFallback implements HystrixClient {
@Override
public Hello iFailSometimes() {
return new Hello("fallback");
}
}
复制代码
If you want to know the reason for the downgrade, you configure fallbackFactory property in @FeignClient
FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
protected interface HystrixClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello iFailSometimes();
}
@Component
static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
@Override
public HystrixClient create(Throwable cause) {
return new HystrixClient() {
@Override
public Hello iFailSometimes() {
return new Hello("fallback; reason was: " + cause.getMessage());
}
};
}
}
复制代码
Simply put, the above demo at how to achieve a downgrade. But the downgrade policies do not support the method return com.netflix.hystrix.HystrixCommand
and rx.Observable 的情况。
## six, Feign and @Primary
When downscaling strategy Feign Hystrix, if the instance of the same type ApplicationContext. @Autowired will error when using injection must be used @Primary comment. For normal operation, Spring Cloud to all Feign instances are marked @Primary comment. But this will be a problem in some cases, provide a way for all closed, you can @FeignClient primary attribute is set to false.
FeignClient(name = "hello", primary = false)
public interface HelloClient {
// methods here
}
复制代码
## seven, Feign request / response compression can be turned request / response GZIP compression function, configure the properties on the list feign.compression.request.enabled = true feign.compression.response.enabled = true
还有几个web server的配置 feign.compression.request.enabled=true feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048
## eight, Feign logging can use the fully qualified class name is Feing Client create a logger, logger level DEBUG logging.level.project.user.UserClient: DEBUG can be configured to set how the print log Logger.Level
NONE, no printing (DEFAULT). BASIC, only the recording method and the URL request and response status code and execution time HEADERS, record basic information and the request and response headers. Header FULL, record requests and responses, text and metadata
@Configuration
public class FooConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
复制代码
Reproduced in: https: //juejin.im/post/5d0467986fb9a07eb67d8d56