Spring Cloud learning note 4: custom configuration and use of Feign for building micro Service Engineering

catalogue

Custom configuration and use of Feign

Log configuration

Contract allocation

Basic authentication configuration

Timeout configuration

Client component configuration

GZIP compression configuration

Encoder decoder configuration

Customize Feign's configuration using configuration

Inheritance characteristics

Multi parameter request construction

 

Custom configuration and use of Feign

 

Log configuration

Sometimes when we encounter bugs, such as interface call failure, parameters not received, or want to see the call performance, we need to configure Feign's log to let Feign output the request information. First, define a configuration class. The code is as follows:
 

@Configuration
public class FeignConfig {
    /**
     * log level
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

From the source code, you can see that there are four log levels, namely:

  • NONE: do not output logs.

  • BASIC: only the URL of the request method, the status code of the response and the execution time of the interface are output.

  • HEADERS: output BASIC information and request header information.

  • FULL: output complete request information.

After the configuration class is built, we need to specify the configuration class to be used in the @ FeignClient annotation in Feign Client. The code is as follows:

@FeignClient(value = "blog-user-service", configuration = FeignConfig.class)
@RequestMapping("/user")
public interface UserFeignClient {
  // ...
}

Only by executing the log level of the Client in the configuration file can the log be output normally. The format is "logging.level.client class address = level".

logging.level.cn.com.stary1993.blog.client.UserFeignClient=DEBUG

Finally, call our / user/query/1 interface through Feign, and you can see the call information output from the console.

 

Contract allocation

Spring Cloud is extended on the basis of Feign, which can be called with Spring MVC annotations. The native Feign does not support Spring MVC annotations.

If you want to use the native annotation method to define the client in Spring Cloud, you can also change the configuration through the configuration contract. The default in Spring Cloud is spring mvccontract, and the code is as follows:

@Configuration
public class FeignConfig {
    /**
     * Use native feign annotations
     * @return
     */
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}

After you configure to use the default contract, the previously defined Client will not be used. The previous annotation above is the annotation of Spring MVC. Now you need to use Feign's annotation:

@FeignClient(value = "blog-user-service", configuration = FeignConfig.class)
//  @RequestMapping("/user")
public interface UserFeignClient {

 	// @GetMapping("/{id}")
    @RequestLine("GET /user/{id}")
    String findById(
    // @PathVariable(value = "id")
    @Param(value = "id") Integer id);

}

 

Basic authentication configuration

Generally, the interfaces we call have permission control. In many cases, the authentication value may be passed through parameters, and the authentication information is passed through the request header, such as Basic authentication. In Feign, we can directly configure Basic authentication. The code is as follows:

/**
 * Basic authentication
 * @return
 */
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    return new BasicAuthRequestInterceptor("user", "password");
}

Or you can customize your own authentication method. In fact, you can customize a request interceptor. Do the authentication operation before the request, and then set the information after authentication in the request header. The authentication method is defined by implementing the RequestInterceptor interface. The code is as follows:

public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
    public FeignBasicAuthRequestInterceptor() {
    }
    @Override
    public void apply(RequestTemplate template) {
        // Business logic
    }
}

Then change the configuration to our custom one, so that when Feign requests the interface, it will enter the apply method of FeignBasicAuthRequestInterceptor before each request, and your logic can be done in it. The code is as follows:

    /**
     * Custom Basic authentication
     * @return
     */
    @Bean
    public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new FeignBasicAuthRequestInterceptor();
    }

When restarting the service and accessing the interface, you can see the change of the log request header printed on the console:

c.c.s.blog.client.UserFeignClient        : [UserFeignClient#findById] Authorization: Basic dXNlcjpwYXNzd29yZA==

 

Timeout configuration

The connection timeout and read timeout can be configured through Options. The first parameter of Options is the connection timeout (ms), and the default value is 10 × 1000; The second is to take the timeout (ms), and the default value is 60 × 1000.

    /**
     * Configure timeout
     * @return
     */
    @Bean
    public Request.Options options() {
        return new Request.Options(5000, TimeUnit.MILLISECONDS,
                10000, TimeUnit.MILLISECONDS, true);
    }

 

Client component configuration

In Feign, the JDK native URLConnection is used by default to send HTTP requests. We can integrate other components to replace URLConnection, such as Apache HttpClient and OkHttp.

To configure OkHttp, you only need to add OkHttp dependencies. The code is as follows:

        <!-- feign-okhttp -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

Then modify the configuration, disable Feign's HttpClient and enable OkHttp. The configuration is as follows:

feign:
  httpclient:
    enabled: false
  okhttp:
    enabled: true

 

GZIP compression configuration

Enabling compression can effectively save network resources and improve interface performance. We can configure GZIP to compress data:

feign:
  compression:
    request:
      enabled: true
    response:
      enabled: true

You can also configure the compression type and the standard of the minimum compression value:

feign:
  compression:
    request:
      enabled: true
      # Minimum compression value
      min-request-size: 2048
      # Type of compression
      mime-types: text/xml,application/xml,application/json

The compression will take effect only when Feign's Http Client is not okhttp3. The configuration source code is at org spring-framework. cloud. openfeign. encoding. Feignacceptgzipencodingautoconfiguration, the code is as follows:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({FeignClientEncodingProperties.class})
@ConditionalOnClass({Feign.class})
@ConditionalOnBean({Client.class})
@ConditionalOnProperty(value = {"feign.compression.response.enabled"}, matchIfMissing = false)
@ConditionalOnMissingBean(type = {"okhttp3.OkHttpClient"})
@AutoConfigureAfter({FeignAutoConfiguration.class})
public class FeignAcceptGzipEncodingAutoConfiguration {
    public FeignAcceptGzipEncodingAutoConfiguration() {
    }

    @Bean
    public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
        return new FeignAcceptGzipEncodingInterceptor(properties);
    }
}

The core code is @ ConditionalOnMissingBean(type = {"okhttp3.OkHttpClient"}), which means that the conditions match when the specified bean is not included in the Spring BeanFactory, that is, compression configuration will be carried out only when okhttp3 is not enabled.

When restarting the service and accessing the interface, you can see the change of the log request header printed on the console:

c.c.s.blog.client.UserFeignClient        : [UserFeignClient#findById] Accept-Encoding: gzip
c.c.s.blog.client.UserFeignClient        : [UserFeignClient#findById] Accept-Encoding: deflate

 

Encoder decoder configuration

Feign provides customized codec settings, as well as the implementation of various encoders, such as Gson, Jaxb and Jackson. We can use different codecs to process data transmission. If you want to transmit data in XML format, you can customize the XML codec to obtain it and use the official Jaxb.

To configure codec, you only need to register Decoder and Encoder in Feign's configuration class. The code is as follows:

@Bean
public Decoder decoder() {
    return new MyDecoder();
}

@Bean
public Encoder encoder() {
    return new MyEncoder();
}

 

Customize Feign's configuration using configuration

# Link timeout
feign.client.config.feignName.connectTimeout=5000
# Read timeout
feign.client.config.feignName.readTimeout=5000
# Log level
feign.client.config.feignName.loggerLevel=full
# retry 
feign.client.config.feignName.retryer=com.example.SimpleRetryer
# Interceptor
feign.client.config.feignName.requestInterceptors[0]=com.example.FooRequestInterceptor
feign.client.config.feignName.requestInterceptors[1]=com.example.BarRequestInterceptor
# encoder
feign.client.config.feignName.encoder=com.example.SimpleEncoder
# decoder
feign.client.config.feignName.decoder=com.example.SimpleDecoder
# contract
feign.client.config.feignName.contract=com.example.SimpleContract

 

Inheritance characteristics

Omit...

 

Multi parameter request construction

Omit...

 

Tags: Java Distribution Spring Cloud

Posted by dgx on Sat, 16 Apr 2022 09:43:51 +0930