[Spring Cloud Series] Detailed explanation and practical combat of Feign

Detailed explanation and practical combat of Feign

Article directory

I. Overview

The usage of Ribbon was introduced in the previous chapter. When using Ribbon to call the API of other services through RestTemplate, all parameters must be spliced ​​in the requested URL. If there are too many parameters, splicing the request string will lead to a decrease in efficiency. Spring Cloud provides another solution for calling APIs, using Spring Cloud Feign .

2. What is Feign?

Feign is a load-balanced HTTP client that wraps Ribbon. Calling an API using Feign is just like calling a native method. This avoids the tedious steps of constantly encapsulating/parsing Json data when calling microservices.

Feign is a declarative web client that makes writing web service clients easier. Use Fegin to create an interface and annotate it. It has pluggable annotation support including Fegin annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spirng Cloud adds annotation capabilities to Spring MVC. Feign integrates Ribbon by default, so Fegin achieves load balancing by default.

3. Feign characteristics

  • Supports pluggable HTTP encoders and decoders
  • Support Hystrix and its Fallback;
  • Support Ribbon load balancing;
  • Supports compression of HTTP requests and responses.

4. Feign is easy to use

3.1 Feign usage steps

  1. Introduce dependencies
  2. Add annotations to the startup class
  3. Write FeignClient interface
  4. Use Feign to initiate an http request
  5. Configure Feign log

3.2 Specific use of Feign

1. Introduce dependencies
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. Add annotations to the startup class
@MapperScan("com.goyeer")
@SpringBootApplication
@EnableFeignClients
public class GoyeerApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderApplication.class, args);
    }
}

3. Write the FeignClient interface
@FeignClient("orderservice")
public interface OrderClient {
    
    
    @GetMapping("/Order/findById")
    Order findById(@PathVariable("orderId") Long orderId);
}

5. Use Feign to initiate an http request

5.1 Maven imports Feign configuration and integrates Jackson

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 用于解析数据 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-jackson</artifactId>
    <version>9.7.0</version>
</dependency>

5.2 Feign sending path and method settings

@RequestLine("GET /user/getone?arkOrgId={arkOrgId}&userId={userId}")
JSONObject getOneEmployee(@Param("orgId") String orgId,@Param("userId") String userId);

@RequestLine("POST /user/add")
@Headers("Content-Type: application/json")
@Body("{body}")
JSONObject saveEmployee(@Param("body") EmployeeDTO employeeDTO);

5.3 Call Feign.bulider() to specify the request uri and call the method in the interface

public class App{
    
    
    public static void main(String[] args){
    
    
        EmloyeeAPI emloyeeAPI = Feign.builder().target(EmloyeeAPI.class,"http://localhost:8088");
        String result = emloyeeAPI.getOneEmployee("110","1110");
        System.out.println(result);
    }
}

6. Common annotations for Feign interface

annotation type illustrate
@RequestLine Method Define its request method and request path (UriTemplate). The request path starts with a slash, and {variable name} can be used in the middle. The value of the expression is provided by the @Param annotation.
@Param Parameter Define a variable template, and the value of the variable can be referenced through the expression {variable name}
@Headers Method,Type To define the request header, you can use {variable name}, and the value of the expression is provided by the @Param annotation.
@QueryMap Parameter Define Map or Pojo type parameters.
@HeaderMap Parameter Define the request header of Map type
@Body Method Extension of @Param, used with @Headers to define JSON and XML type parameters

7. Feign interface and common annotations

7.1 target method

Specify the interface type and URL address to interface with the Http proxy object, so as to send HTTP requests through the proxy object calling method.

7.2 client method

Feign uses the JDK's native URLConnection to send HTTP requests by default.

7.3 options method

Specify the connection timeout duration and response timeout duration, in milliseconds.

7.4 retryer method

Specify the retry strategy, the parameters are minimum time, maximum time, and number of reconnections.

7.5 encoder()/decode() method

The default encoding/decoding method is String.

7.6 logger() logLevel()

Specify logs and log levels, configure SLF4J, etc.

7.7 @EnableFeignClients

Used to turn on Feign

7.8 @FeignClient

Mark the request interface to be intercepted with Feign

7.9 value,name

Value has the same function as name. If no url is configured, the configured value will be used as the service name for service discovery. Otherwise it's just a name.

7.10 serviceId

serviceId has been abandoned, just use name directly.

7.11 contextId

Bean name conflict resolved.

7.12 url

The url is used to configure the address of the specified service, which is equivalent to directly requesting this service without going through Ribbon's service selection. It can be used in scenarios such as debugging.

7.13 decode404

When a 404 error occurs in the calling request, and the value of decode404 is true, decoder decoding will be performed, otherwise an exception will be thrown.

7.14 configuration

Configuration is the configuration class of Feign. In the configuration class, you can customize Feign's Encoder, Decoder, LogLevel, Contract, etc.

7.15 fallback

Define the fault-tolerant processing class, that is, the fallback logic. The fallback class must implement the Feign Client interface and cannot know the exception information of the circuit breaker.

7.16 fallbackFactory

It is also a fault-tolerant process, and you can know the abnormal information of the fuse.

7.17 path

path defines the unified prefix when the current FeignClient accesses the interface. For example, the interface address is /user/get. If you define the prefix as user, then the path on the specific method only needs to be written /get.

7.18 primary

Primary corresponds to the @Primary annotation, which defaults to true. There is a reason for the official setting. When our Feign implements fallback, it means that the Feign Client has multiple identical beans in the Spring container. When we use @Autowired to inject, we don’t know which one to inject, so we need to set a high-priority one. Yes, the @Primary annotation does this.

7.19 qualifier

The qualifier corresponds to the @Qualifier annotation. The usage scenario has little to do with the primary above. In general scenarios, @Autowired can be directly injected.

8. Feign’s log level

8.1 Feign’s log level

  • NONE (default): does not record any logs, has the best performance, and is suitable for use in production environments.
  • BASIC: Only records the request method, URL, response status code and execution time, suitable for production environment tracking issues;
  • HEADERS: Record request and response headers based on BASIC level;
  • FULL: Record the Header\Body and metadata of the request and response, used for development and testing to locate problems.

8.2 Feign log configuration method

  • Configuration class global configuration

    Add a configuration class to the project and set the log level as follows, which can be used as a global configuration

    @Configuration
    public class FeignConfig{
          
          
        @Bean
        public Logger.Level level(){
          
          
            return Logger.level.FULL;
        }
    }
    
  • Configuration class local configuration

    First, remove the @Configuration annotation of FeignConfig, otherwise it will be a global configuration.

    The configuration attribute in @FeignClient is assigned FeignConfig.class

    @FeignClient(path = "/employee", value = "provider", configuration = FeignConfig.class)
    public interface UserService {
          
          
        @RequestMapping("/list")
        List<String> findEmployee();
    }
    
  • Configuration file specifies microservice configuration

    In the configuration file, add the following configuration, provider is the server service name, and the configuration change only takes effect when the provider service is called.

    feign.client.config.provider.loggerLevel=BASIC
    

9. Feign principle

4.1 The working principle of Feign service call can be summarized into the following steps:

  1. First enable FeignCleint through the @EnableFeignCleints annotation.
  2. Implement the interface according to Feign's rules and add the @FeignCleint annotation. After the program starts, it will scan all classes with @FeignCleint and inject this information into the ioc container.
  3. Get FeignClient from FeignClientFactoryBean.class when injecting.
  4. When the interface method is called, a specific RequesTemplate is generated through the jdk proxy, and RequesTemplate generates http Reques.
  5. The Request is handed over to the Client for processing, where the Client can be HttpUrlConnection, HttpClient or Okhttp.
  6. Client is encapsulated into the LoadBalanceClient class, which combines with the Ribbon class to achieve load balancing.

4.2 Feign overall flow chart

Insert image description here

10. Similarities and Differences between Feign and Ribbon

Ribbon and Feign are both components that implement load balancing. The essence of Feign is Ribbon and is based on the implementation of Ribbon. They are all annotations added to the consumer side, allowing the consumer side to call the services of other producers.

The difference between Fegin and Ribbon

  • The startup classes use different annotations. Ribbon uses @RibbonClinet and Feign uses @EnableFeignClients.
  • The specified location of the service is different. Ribbon is declared on the @RibbonClient annotation, while Feign is declared using @FeignClient in the interface where the abstract method is defined.
  • The calling methods are different. Ribbon needs to construct the http request by itself, simulate the http request and then use RestTemplate to send it to other services. The steps are quite cumbersome.
  • Ribbon configurable load balancing mechanism

11. Similarities and differences between Feign and RestTemplate

  • RestTemplate

    RestTemplate is an HTTP request tool supported since Spring 3.0. It provides templates for common REST request scenarios, such as GET requests, POST requests, PUT requests, DELETE requests, and some common request execution methods exchange and execute. RestTemplate inherits from InterceptingHttpAccessor and implements the RestOperations interface, which defines basic RESTful operations. These operations are implemented in RestTemplate.

    1. Just add relevant analysis parameters, it is simple and convenient to use.
    2. The fuse node is easy to control, making it easy to make corresponding adjustments based on the business later.
    3. Exception capture is simple, just add the corresponding method on the same page.
    4. The request is closer to httpclient, making it more familiar to use.
    5. High flexibility but bloated message encapsulation.
  • Feign

    A load-balanced HTTP client that uses Feign to call APIs is like calling local methods, avoiding the tedious need to constantly parse/encapsulate json data when calling target microservices. Feign is a declarative web service client. Spring Cloud adds annotations to Spring MVC. Spring Web uses HttpMessageConverters by default. Spring Cloud integrates Ribbon and the load-balanced HTTP client Feign provided by Eureka.

    1. The writing method is elegant and based on interface-oriented style, but it is more cumbersome to develop.
    2. yml needs to add configuration to start the hystrix component.
    3. A corresponding class needs to be created to execute the fallback method.
    4. The interfaces implemented by catching exception information and not catching exceptions are different.
    5. Corresponding parameter configuration needs to be made on the feign annotation.
    6. Any operation in feign requires the creation of various classes to correspond to different parameters.

12. Similarities and differences between Feign and OpenFeign

  • Same point

    1. Feign and OpenFeign are both remote calling and load balancing components under Spring Cloud.
    2. Feign and OpenFeign have the same function and can realize remote invocation and load balancing of services.
    3. Both Feign and OpenFeign have integrated Ribbon, used Ribbon to maintain the list of available services, and implemented client load balancing through Ribbon.
    4. Both Feign and OpenFeign define service binding interfaces on the service consumer (client) and configure them through annotations to achieve remote service invocation.
  • difference

    1. Feign and OpenFeign have different dependencies. Feign's dependency is spring-cloud-starter-feign, while OpenFeign's dependency is spring-cloud-starter-openfeign.
    2. Feign and OpenFeign support different annotations. Feign supports Feign annotations and JAX-RS annotations, but does not support Spring MVC annotations. In addition to supporting Feign annotations and JAX-RS annotations, OpenFeign also supports Spring MVC annotations.

Guess you like

Origin blog.csdn.net/songjianlong/article/details/133103685