This is the fifth day of my participation in the First Challenge 2022

We’ve been able to learn a lot about Getting started with OpenFeign. Today, we’ll take a look at the configuration of OpenFeign performance optimization.

Without further ado, let’s begin today’s lesson.

Log enhancement

You can view the request and response information in F12. If we want to see each interface in the microservice, we can use log configuration to view detailed information.

OpenFeign provides logging enhancements, but does not display any logs by default, although developers can configure their own logging levels during debugging.

The log levels of OpenFeign are as follows:

  • NONE: By default, no logs are displayed.
  • BASIC: only request method, URL, response status code and execution time are recorded;
  • HEADERS: Request and response HEADERS in addition to the information defined in BASIC;
  • FULL: In addition to the information defined in HEADERS, there is the body and metadata of the request and response.

The configuration is as follows:

1. Set the interface log level

Application. Yml file

logging:
  level:
    com.ezhang.auth.service: debug
Copy the code

Com.ezhang.auth. service: debug is the name of the package where the interface resides

Of course, setting the log level using the logback.xml configuration file is the same.

Note:

The Spring Boot Logging configuration is explained in detail in an article by other experts

2. Configure the OpenFeign log level in the configuration class

A custom configuration class in which log levels are set is a global configuration

@Configuration
public class FeignConfiguration {
    @Bean
    Logger.Level feignLoggerLevel(a){
        returnLogger.Level.FULL; }}Copy the code

Local configuration, specified on the client interface

configuration = FeignConfiguration.class

@FeignClient(contextId = "remoteUserService", value = "cloud-system", fallbackFactory = RemoteUserFallbackFactory.class, configuration = FeignConfiguration.class)
public interface RemoteUserService {

    @GetMapping(value = "/user/getUserInfo")
    Map<String, Object> getUserInfo(@RequestParam("userId") int userId);

}
Copy the code

Effect of 3.

Send a request to http://localhost:9203/test/getUserInfo? UserId =2, the console can see the detailed request information.

GZIP compression

introduce

Gzip is a data format that uses deflate to compress data; Gzip is a popular file compression algorithm that is widely used, especially on Linux platforms.

Ability to

When Gzip is compressed to a plain text file, the effect is dramatic, reducing the file size by more than 70%.

role

Network data compression actually reduces the number of bytes transmitted over the network, the most obvious benefit being that it speeds up web page loading. The benefits of faster web page loading are self-evident. In addition to saving traffic and improving user browsing experience, another potential benefit is that Gzip has a better relationship with search engine scraping tools. Google, for example, can retrieve web pages faster than normal manual crawling by reading gzip files directly.

OpenFeign To enable GZIP:

1. Enable gzip compression in the project

server:
  port: 9203
  Whether to enable compression
  compression:
    enabled: true
    # Configure MINE TYPE to support compression
    mime-types: text/html,text/xml,text/plain,application/xml,application/json
Copy the code

2. Enable gzip compression on the Feign service provider

feign:
  compression:
    request:
      # enable request compression
      enabled: true
      # Configure MINE TYPE to support compression
      mime-types: text/xml,application/xml,application/json
      # set a lower limit on the size of compressed data
      min-request-size: 2048
    response:
      Turn on response compression
      enabled: true
Copy the code

Effect of 3.

After the above configuration is complete, initiate the request and observe the console log:

The Http connection pool

The process of establishing an HTTP connection between two servers involves the exchange of multiple packets, which is very time consuming. Using HTTP connection pooling can save a lot of time in prompt throughput.

Feign’s HTTP client supports three frameworks: HttpURLConnection, HttpClient, and OkHttp.

Observe the source code can be found, Feign default is USES the java.net.HttpURLConnection, every request will be set up, close the connection.

First check FeignRibbonClient FeignRibbonClientAutoConfiguration automatic configuration class, the class when start to inject some beans, A Client type Bean with a BeanName of feignClient is injected. The Client.Default object is automatically injected in cases where the Bean BeanName is configured as FeignClient. HttpURLConnection: HttpURLConnection: HttpURLConnection: HttpURLConnection: HttpURLConnection:

public static class Default implements Client {
    private final SSLSocketFactory sslContextFactory;
    private final HostnameVerifier hostnameVerifier;
    private final boolean disableRequestBuffering;
    
    public Response execute(Request request, Options options) throws IOException {
        HttpURLConnection connection = this.convertAndSend(request, options);
        return this.convertResponse(connection, request);
    }
    // omit other sources
}
Copy the code

For the sake of performance, we can introduce HttpClient and OKHTTP as the underlying communication framework.

For example, change Feign’s HTTP client tool to HttpClient.

1. Add dependencies

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>
Copy the code

2. Enable it in the configuration file

feign:
  # open httpclient
  httpclient:
    enabled: true
Copy the code

3. How to verify

In feign. SynchronousMethodHandler# executeAndDecode () the way in which the client can see clear calls.

Before replacing HttpClient, it looks like this:

After a successful replacement it looks like this:

4. Source code analysis

We HttpClientFeignLoadBalancedConfiguration to view source code:

@Configuration( proxyBeanMethods = false )
@ConditionalOnClass({ApacheHttpClient.class})
@ConditionalOnProperty( value = {"feign.httpclient.enabled"}, matchIfMissing = true )
@Import({HttpClientFeignConfiguration.class})
class HttpClientFeignLoadBalancedConfiguration {
    HttpClientFeignLoadBalancedConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean({Client.class})
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory, HttpClient httpClient) {
        ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
        return newLoadBalancerFeignClient(delegate, cachingFactory, clientFactory); }}Copy the code

The @conditionalonProperty annotation indicates that httpClient is enabled in the configuration file, since it is true by default.

@ Import ({HttpClientFeignConfiguration. Class}) HttpClientFeignConfiguration this configuration class interested friends can look at ourselves.

Fusing the drop

Common fuse downgrading frameworks include Hystrix and Sentinel, and openFeign supports Hystrix by default.

In fact, in the previous article, there was a detailed introduction to the Implementation of circuit breaker degradation microservices series: OpenFeign for Service Invocation of Spring Cloud

fallbackFactory = RemoteUserFallbackFactory.class

I won’t repeat it here. It can be switched to integrated Sentinel to achieve fuse downgrading.

The core code is basically the same for Both Hystrix and Sentinel support for Feign, just changing the dependencies and configuration files.

other

In addition to these optimizations, there is a request timeout configuration, which is ready to write a whole article. Because I feel like I can’t do it in small pieces…

Feign can set the request timeout, ribbon can set it, hystrix can set it.

How to take into account the relationships among the ribbon, Feign, and Hystrix, and add appropriate configurations to make each component perform its own functions and cooperate with each other is a difficult problem.

It makes my head bald to think about it.

PS: Now that you’ve seen it, give it a thumbs up, Daniel!

Who can stand that?