One, understand Feign
1. What is Feign
Netflix Feign
Feign is a declarative and templated HTTP client developed by Netflix. Feign can help us call HTTP APIs more quickly and gracefully.
Feign is actually a layer of encapsulation for ordinary HTTP clients, and its purpose is to reduce integration costs and improve reliability. Feign supports three kinds of HTTP clients, including HttpURLConnection, Apache HttpClient and Square OkHttp that come with the JDK. Apache HttpClient is used by default.
Spring Cloud Feign
Spring Cloud Feign is based on the implementation of Netflix Feign, which enhances Netflix Feign, enabling Feign to support Spring MVC annotations, integrating Spring Cloud Ribbon and Spring Cloud Hystrix to provide load balancing and circuit breakers.
2,Feign和Open Feign
In fact, Feign and Open Feign belong to the same thing, Feign 仅仅只是改名成为了
Open Feign, and the Open Feign project continues to develop on its basis.
spring-cloud-starter-feign has abandoned Netflix Feign from the 1.2.0.RELEASE
beginning and fully uses the updated Open Feign version,
spring-cloud-starter-openfeign has nothing to do with Netflix Feign.
Second, the use of Feign
1. Use by service consumers
1.1, start an eureka service:
1.2, register a service provider eureka-provider to eureka-server
application.yaml
spring:
application:
name: eureka-provider
eureka:
client:
service-url:
defaultZone: http://euk-server1:7001/eureka/
instance:
hostname: euk-client1
HelloController.java
@RestController
public class HelloController {
@Value("${server.port}")
private String port;
@GetMapping("/testFeign")
public String testFeign() {
System.out.println("port:" + port);
return "服务提供者,端口为:" + port;
}
}
1.3, use Feign to register service consumers with eureka-server
Import Open Feign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Configure the appliation.yml to register to Eureka Server.
eureka:
instance:
hostname: localhost
client:
service-url:
defaultZone: http://euk-server1:7001/eureka/
spring:
application:
name: eureka-consumer
server:
port: 7008
Use @FeignClient to declare a simple callable client for this application, and value is the name of the service that needs to be called.
@FeignClient(value = "eureka-provider")
public interface FeignInterface {
@RequestMapping("/testFeign")
public String testFeign();
}
Receive external requests and call services remotely through Feign
@RestController
public class FeignController {
@Autowired
private FeignInterface feignInterface;
@RequestMapping("/testFeign")
public String testFeign() {
return feignInterface.testFeign();
}
}
Add @EnableFeignClients to the startup class to enable Feign
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EurekaConsumer1Application {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumer1Application.class, args);
}
}
Start eureka-consumer and visit http://localhost:7008/testFeign to return the result:
2. Fegin's inheritance features use
Spring Cloud Feign provides inheritance features. The so-called inheritance feature extracts some common operations into a parent interface, thereby inheriting the operations in the parent interface, reducing repetitive development of code and saving development costs.
- Write a general service interface A, write @RequestMapping() on the interface method, this interface is used for feign.
- The service provider implements interface A above.
- The feign client interface of the service consumer inherits A.
advantage:
The definition of the interface can be stripped from the Controller , and at the same time, with the Maven private warehouse, the sharing of the interface definition can be easily realized. There is no need to copy and paste the interface for binding, but to realize the interface binding during the construction period, thereby effectively reducing the service customers End binding configuration.
Disadvantages:
Since the interface builds a dependency during the construction period, the interface change will have an impact on the project construction, and the service provider may modify an interface definition, which will directly cause the construction of the client project to fail.
2.1: First, we create a new general model, eureka-feign-api
Since we need to use spring mvc, the pom.xml depends on the spring web module
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Create a general interface HelloInterface.java for eureka-provider implementation, eureka-consumer inheritance:
@RequestMapping("/feign")
@RestController
public interface HelloInterface {
@GetMapping("/hello")
String hello();
}
2.2: eureka-provider relies on eureka-feign-api and implements its general interface HelloInterface
eureka-provider's pom adds dependency eureka-feign-api
<dependency>
<groupId>com.bobo</groupId>
<artifactId>eureka-feign-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
The controller of eureka-provider implements the generic interface HelloInterface
@RestController
public class FeignCommonProviderController implements HelloInterface {
@Value("${server.port}")
private int port;
@Override
public String hello() {
return "服务提供者,我的端口为:" + port;
}
}
eureka-provider startup class
@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
3.3: eureka-consumer depends on eureka-feign-api and inherits its general interface HelloInterface
Add eureka-feign-api to eureka-consumer's pom dependency
<dependency>
<groupId>com.bobo</groupId>
<artifactId>eureka-feign-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
eureka-consumer inherits the generic interface HelloInterface
@FeignClient("eureka-provider")
public interface FeignCommonInterface extends HelloInterface {
}
eureka-consumer implements Feign calls through FeignCommonInterface
@RestController
public class FeignCommonController {
@Autowired
private FeignCommonInterface commonInterface;
@GetMapping("/hello")
public String hello(){
return commonInterface.hello();
}
}
eureka-consumer startup class
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class EurekaConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class, args);
}
}
Then start eureka-server, eureka-provider, eureka-consumer, and call eureka-consumer through the service
http://euk-client2:7008/hello output:
Three, Feign configuration
The default configuration class of feign is: org.springframework.cloud.openfeign.FeignClientsConfiguration. The encoder, decoder, etc. used by feign are defined by default.
Feign allows custom configuration. There are two ways to customize configuration:
- One is Java code configuration, which needs to be referenced in @FeignClient(name = "eureka-consumer", configuration = FeignAuthConfiguration.class).
- The second is the direct configuration file configuration, which is configured in application.yml or application.properties.
1. Java code configuration
public class FeignAutoConfiguration {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("root", "root");
}
}
@FeignClient(value = "eureka-provider",configuration = FeignAutoConfiguration.class)
public interface FeignCommonInterface extends HelloInterface {
}
If the @Configuration annotation is added to the configuration class and the class is in the package scanned by @ComponentScan, then the configuration information in this class will be shared by all @FeignClient.
The best practice is: do not specify the @Configuration annotation, but manually: @FeignClient(name = "eureka-provider", configuration = FeignAuthConfiguration.class)
2. Configuration file configuration
Custom interceptor:
/**
* @author bobo
* @date 2020-12-08
* 自定义拦截器
*/
public class MyBasicAuthRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("Authorization", "Basic cm9vdDpyb290");
}
}
application.yaml
spring:
application:
name: eureka-consumer
eureka:
client:
service-url:
defaultZone: http://euk-server1:7001/eureka/
instance:
hostname: euk-client2
server:
port: 7008
feign:
client:
config:
eureka-peovider:
request-interceptors:
com.bobo.eurekaconsumer.MyBasicAuthRequestInterceptor
3. Extension
Custom service name configuration:
feign:
client:
config:
service-valuation:
connect-timeout: 5000
read-timeout: 5000
logger-level: full
General placement:
feign:
client:
config:
default:
connect-timeout: 5000
read-timeout: 5000
logger-level: full
4. Feign compression
Spring Cloud Feign supports GZIP compression for requests and responses to improve communication efficiency, but it will increase the CPU pressure. It is recommended to increase the minimum compressed document size appropriately and perform gzip compression.
# 开启GZIP压缩配置:
#请求GZIP压缩
feign.compression.request.enable=true
#响应GIZP压缩
feign.compression.response.enable=true
#压缩支持的mime type
feign.compression.request.mime-types=text/xml,application/xml.application/json
feign.compression.request.min-request-size=1024
#压缩数据大小的最小值
5. Feign log
Feign provides an instance of feign.logger for each FeignClient, which can be turned on in the configuration or java code.
feign:
client:
config:
# 服务名称
eureka-provider:
logger-level: basic
The above logger-level has 4 log types:
- none: Do not record any logs, the default value.
- basic: Only record the request method, url, response status code, and execution time.
- headers: Record header information on the basis of basic.
- full: Record the header, body, and metadata of the request and response.
The above logger-level only responds to the following debug level logs:
logging:
level:
com.bobo.eureka-consumer.ServiceForecast: debug
Four, write at the end
The above example code has been uploaded to Code Cloud: https://gitee.com/songbozhao/spring-cloud-feign-test