Http client feign for microservices

Problems with calling RestTemplate

Let's first take a look at the code of the remote call initiated by RestTemplate:

String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);

There are the following problems:

1. Poor code readability and inconsistent programming experience

2. URL s with complex parameters are difficult to maintain


Introduction, definition and use of Feign



The steps to use Feign are as follows:

1. Introduce dependencies:


2. Add annotations to the startup class of the microservices that need to be used to enable the Feign function:



3. Write Feign client:

public interface UserClient {
    User findById(@PathVariable("id") Long id);

It is mainly based on SpringMVC annotations to declare remote call information, such as: Service name: userservice Request method: GET Request path: /user/{id} Request parameter: Long id Return value type: User

4. Replace RestTemplate with Feign client







Customize the configuration of Feign:

Feign runs a custom configuration to override the default configuration. The configuration that can be modified is as follows:




There are two ways to configure Feign logs:

Method 1: configuration file method

1. Take effect globally:

      default: # Here default is the global configuration, if it is to write the service name, it is the configuration for a microservice
        loggerLevel: FULL #  log level 

2. Partial effect:

      userservice: # Here default is the global configuration, if it is to write the service name, it is the configuration for a microservice
        loggerLevel: FULL #  log level 

Method 2: java code method, you need to declare a Bean in advance:

public class FeignClientConfiguration {
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; 

1. Then if it is a global configuration, put it in the @EnableFeignClients annotation:

@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class) 

2. If it is a partial configuration, put it in the @FeignClient annotation:

@FeignClient(value = "userservice", configuration = FeignClientConfiguration.class) 





Fegin performance optimization:

The underlying client implementation of Feign:

URLConnection: default implementation, does not support connection pooling

Apache HttpClient: support connection pool

OKHttp: support connection pool


Therefore, optimizing the performance of Feign mainly includes:

Use a connection pool instead of the default URLConnection

log level, preferably basic or none


Feign adds HttpClient support:


1. Introduce dependencies:

<!--httpClient dependence on -->

2. Configure the connection pool

      default: # default global configuration
        loggerLevel: BASIC # Log level, BASIC is the basic request and response information 
    enabled: true # Enable feign's support for HttpClient
    max-connections: 200 # maximum number of connections
    max-connections-per-route: 50 # Maximum number of connections per path




Feign's best practice and optimization

Method 1 (inheritance): Define a unified standard parent interface for the consumer's FeignClien and the provider's controller as a standard (not recommended



Method 2 (extraction): Extract Feign as an independent module, and put the interface-related POJO and default Feign configuration into this module for all consumers to use




The steps to implement Best Practice Method 2 are as follows:

1. First create a module named feign-api, and then introduce feign's starter dependency

2. Copy the UserClient, User, and DefaultFeignConfiguration written in order-service to the feign-api project

3. Introduce feign-api dependency in order-service

4. Modify all the import parts related to the above three components in order-service, and change them to import the package in feign-api

restart test


When the defined FeignClient is not in the scope of SpringBootApplication's scan package, these FeignClients cannot be used. There are two ways to solve it:

Method 1: Specify the package where FeignClient is located, and scan an entire package

@EnableFeignClients(basePackages = "cn.itcast.feign.clients")

Method 2: Specify the FeignClient bytecode, scan the required client, and recommend using method 2 to achieve the effect of only using the required client

@EnableFeignClients(clients = {UserClient.class})


Tags: Microservices

Posted by FoTo50 on Fri, 25 Nov 2022 13:21:20 +1030