SpringCloud OpenFeign

OpenFeign

1. What is OpenFeign?

Feign is a declarative WebService client. Using Feign can make writing Web Service clients easier.

Feign is a lightweight RESTful HTTP service client in the Spring Cloud component. Feign has a built-in Ribbon, which is used for client load balancing and calling services in the service registration center.

OpenFeign is that Spring Cloud supports SpringMVC annotations based on Feign, such as @RequestMapping and so on. OpenFeign's @FeignClient can parse the interface under SpringMVC's @RequestMapping annotation and generate implementation classes through dynamic proxy.

2. Spring Cloud integrates OpenFeign

  1. Add openFeign dependency
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. Add Feign client annotation to startup class
@EnableFeignClients
public class  OpsApplication {
    public static void main(String[] args) {
        SpringApplication.run(OpsApplication.class, args);
    }
}
  1. Writing Feign calls
@FeignClient(name = "zm-teachers", path = "/teacherInfo")
public interface TeacherClient {
    
    
    
}

3. OpenFeign features

1. Timeout configuration

The connection timeout and read timeout can be configured through Options. The first parameter of Options is the connection timeout (ms); the second is the request processing timeout (ms).

  • Configuration class configuration, global configuration
@Configuration
public class FeignConfig {
    
    
    @Bean
    public Request.Options options(){
    
    
        return new Request.Options(5000,10000);
    }
}
  • Configuration class configuration, local configuration
@FeignClient(name = "zm-teachers",configuration = FeignConfig.class)
public interface TeacherClient {
    
    
}

public class FeignConfig {
    
    
    @Bean
    public Request.Options options(){
    
    
        return new Request.Options(5000,10000);
    }
}
  • Configuration file configuration, global configuration
#连接超时时间 单位:ms
feign.client.config.default.connectTimeout:5000
#请求处理超时时间 单位:ms
feign.client.config.default.connectTimeout:3000
  • Configuration file configuration, local configuration
#连接超时时间 单位:ms
feign.client.config.zm-teachers.connectTimeout:5000
#请求处理超时时间 单位:ms
feign.client.config.zm-teachers.connectTimeout:3000

2. Log configuration

Log level

Log level Applicable scene content
NONE (default) Best performance, suitable for production Does not generate any logs
BASIC Suitable for production environment testing problems Record request method, URL response status code and execution time
HEADERS Based on BASIC, record the request and response headers
FULL Suitable for development and testing environment positioning problems Record headers, bogy, and metadata of requests and responses
  • Configuration class configuration, global configuration

    @Configuration
    public class FeignConfig {
          
          
        //日志级别
        @Bean
        public Logger.Level feignLoggerLevel(){
          
          
            return Logger.Level.FULL;
        }
    }
    
  • Configuration class configuration, local configuration

    @FeignClient(name = "zm-teachers",configuration = FeignConfig.class)
    public interface TeacherClient {
          
          
    }
    
    public class FeignConfig {
          
          
       //日志级别
        @Bean
        public Logger.Level feignLoggerLevel(){
          
          
            return Logger.Level.FULL;
        }
    }
    
  • Configuration file configuration, global configuration

    feign.client.config.default.loggerLevel:FULL
    
  • Configuration file configuration, local configuration

    feign.client.config.zm-teachers.loggerLevel:FULL
    

3. Communication components

  • OkHttp

    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-okhttp</artifactId>
    </dependency>
    
    feign.okhttp.enabled:true
    
  • HttpClient

    <dependency>
       <groupId>io.github.openfeign</groupId>
       <artifactId>feign-httpclient</artifactId>
    </dependency>
    
    feign.httpclient.enabled:true
    

4. Gzip compression

Data length limits for GET requests and POST requests

Theoretically, there is no limit to the data length of GET requests and POST requests, but servers and browsers will limit them.

  • Browser restrictions: In order to be compatible with the length requests of various browsers, the URL length is limited to [2083] characters. (IE: 2083, Firefox: 65536, Chrome: 8182)
  • Server limitations:
    • tomecat:maxHttpHeaderSize parameter
    • nginx:large_client_header_buffers参数

feign data compression configuration

#开启feign请求压缩,默认不开始
feign.compression.reqest.enabled:true
#配置支持压缩的MIME TYPE,默认为:text/xml,application/xml,application/json
feign.compression.reqest.mime-types:text/xml,application/xml,application/json
#触发请求数据压缩的最小Size,默认2048KB
feign.compression.reqest.min-request-size: 2048

#开启Feign响应压缩,默认不开启
feign.compression.response.enabled:true
#使用GZip解码器,默认不使用
feign.compression.response.useGzipDecoder:true

Data compression places a burden on the CPU

Note, if the communication component uses okhttp3, Gzip will not take effect.

/*
 * Copyright 2013-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.openfeign.encoding;

import feign.Client;
import feign.Feign;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Configures the Feign response compression.
 *
 * @author Jakub Narloch
 * @see FeignAcceptGzipEncodingInterceptor
 */
@Configuration
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(Client.class)
@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false)
//The OK HTTP client uses "transparent" compression.
//If the accept-encoding header is present it disable transparent compression
@ConditionalOnMissingBean(type = "okhttp3.OkHttpClient")
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignAcceptGzipEncodingAutoConfiguration {
    
    

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

5. Load balancing

Load balancing configuration

zm-teachers.ribbon.NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule
zm-teachers.ribbon.ConnectTimeout: 250                 # 连接超时时间
zm-teachers.ribbon. ReadTimeout: 1000                   # ribbon 读取超时时间
zm-teachers.ribbon. OkToRetryOnAllOperations: true      # 是否对所有操作都进行重试
zm-teachers.ribbon.MaxAutoRetriesNextServer: 1         # 切换实例的重试次数
zm-teachers.ribbon.MaxAutoRetries: 1                   # 对当前实例的重试次数
Load balancing strategy illustrate
Weight strategy/WeightedResponseTimeRule A weight is assigned based on the response time of each service provider. The longer the response time, the smaller the weight, and the lower the possibility of being selected. Implementation principle: Just start using the polling strategy and start a timer, collect the average response time provided by all services at regular intervals, and then attach a weight to each service provider. The higher the weight, the greater the probability of being selected. big.
Minimum number of connections strategy/BestAvailableRule Also called the minimum concurrency strategy, it traverses the service provider list and selects a service instance with the smallest number of connections. If there are the same minimum number of connections, the polling strategy will be called for selection.
Zone Sensitivity Policy/ZoneAvoidanceRule Service instances are selected based on the performance of the region where the service is located and the availability of the service. In an environment without a region, the change strategy is similar to the polling strategy.
Available Sensitivity Policy/AvailabilityFilteringRule First filter out unhealthy service instances, and then select service instances with a smaller number of connections.
Random Strategy/RandomRule Randomly select a service instance from the list of service providers
Retry strategy/RetryRule Obtain the service according to the polling policy. If the obtained service is null or has expired, retry to obtain the service within the specified time. If the service instance is still not obtained after the specified time, null is returned.

6. Hystrix

Problems faced by complex distributed services: service avalanche

Methods to solve service avalanche: downgrade, isolation, circuit breaker, request caching, request merging.

<dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

Two ways of Hystrix callback:

  1. fallback
@FeignClient(name = "zm-biz-import-service"fallback = ImportClientHystrix.class)
public interface ImportClient {
    
    
    @RequestMapping(method = RequestMethod.POST, path = "/upload/single/file" ,produces = {
    
    MediaType.APPLICATION_JSON_UTF8_VALUE}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    Result<TeacherUploadDto> uploadSingleFile(MultipartFile  param);
}

@Component
public class ImportClientHystrix implements ImportClient {
    
    

    @Override
    public Result<TeacherUploadDto> uploadSingleFile(MultipartFile param) {
    
    
        log.warn("ImportClientHystrix uploadSingleFile error ");
        return Result.error();
    }
}
  1. fallbackFactory
@FeignClient(name = "zmbiz-asset-query", fallbackFactory = AssetQueryFeignClientFallbackFactory.class)
public interface AssetQueryFeignClient {
    
    

    /**
     * @return 根据学生ID查询student_money
     * @param
     * @return
     */
    @GetMapping(value = "/api/studentMoney/queryByStuId")
    HaloResult<List<StudentMoneyDTO>> queryStudentMoneyByStuId(@RequestParam(value = "stuId") Integer stuId);
}

@Component
@Slf4j
public class AssetQueryFeignClientFallbackFactory implements FallbackFactory<AssetQueryFeignClient> {
    
    
    @Override
    public AssetQueryFeignClient create(Throwable cause) {
    
    
        return new AssetQueryFeignClient() {
    
    
            @Override
            public Result<User> addPerson(User user) {
    
    
                log.warn("调用zmbiz-user-business服务调用异常,uri = /tBsPerson/add/person, para = {}, e = {}", JSONObject.toJSONString(user), ExceptionUtils.getFullStackTrace(e));
                return Result.errorMessage("亲,服务器升级中,请稍后再试!");
            }
        };
    }
}

It is recommended to use fallbackFactory. You can check the cause of the problem by printing downgrade exceptions.

hystrix configuration

feign.hystrix.enabled:true

#方案一:配置核心线程数量,以及最大线程数量

hystrix.threadpool.default.coreSize = 50
hystrix.threadpool.default.maximumSize = 100
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize = true

#方案二:配置队列长度以及拒绝长度

hystrix.threadpool.default.maxQueueSize: 1000 #BlockingQueue的最大队列数,默认值-1
hystrix.threadpool.default.queueSizeRejectionThreshold: 800 #即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5

OpenFeign

1. What is OpenFeign?

Feign is a declarative WebService client. Using Feign can make writing Web Service clients easier.

Feign is a lightweight RESTful HTTP service client in the Spring Cloud component. Feign has a built-in Ribbon, which is used for client load balancing and calling services in the service registration center.

OpenFeign is that Spring Cloud supports SpringMVC annotations based on Feign, such as @RequestMapping and so on. OpenFeign's @FeignClient can parse the interface under SpringMVC's @RequestMapping annotation and generate implementation classes through dynamic proxy.

2. Spring Cloud integrates OpenFeign

  1. Add openFeign dependency
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. Add Feign client annotation to startup class
@EnableFeignClients
public class  OpsApplication {
    public static void main(String[] args) {
        SpringApplication.run(OpsApplication.class, args);
    }
}
  1. Writing Feign calls
@FeignClient(name = "zm-teachers", path = "/teacherInfo")
public interface TeacherClient {
    
    
    
}

3. OpenFeign features

1. Timeout configuration

The connection timeout and read timeout can be configured through Options. The first parameter of Options is the connection timeout (ms); the second is the request processing timeout (ms).

  • Configuration class configuration, global configuration
@Configuration
public class FeignConfig {
    
    
    @Bean
    public Request.Options options(){
    
    
        return new Request.Options(5000,10000);
    }
}
  • Configuration class configuration, local configuration
@FeignClient(name = "zm-teachers",configuration = FeignConfig.class)
public interface TeacherClient {
    
    
}

public class FeignConfig {
    
    
    @Bean
    public Request.Options options(){
    
    
        return new Request.Options(5000,10000);
    }
}
  • Configuration file configuration, global configuration
#连接超时时间 单位:ms
feign.client.config.default.connectTimeout:5000
#请求处理超时时间 单位:ms
feign.client.config.default.connectTimeout:3000
  • Configuration file configuration, local configuration
#连接超时时间 单位:ms
feign.client.config.zm-teachers.connectTimeout:5000
#请求处理超时时间 单位:ms
feign.client.config.zm-teachers.connectTimeout:3000

2. Log configuration

Log level

Log level Applicable scene content
NONE (default) Best performance, suitable for production Does not generate any logs
BASIC Suitable for production environment testing problems Record request method, URL response status code and execution time
HEADERS Based on BASIC, record the request and response headers
FULL Suitable for development and testing environment positioning problems Record headers, bogy, and metadata of requests and responses
  • Configuration class configuration, global configuration

    @Configuration
    public class FeignConfig {
          
          
        //日志级别
        @Bean
        public Logger.Level feignLoggerLevel(){
          
          
            return Logger.Level.FULL;
        }
    }
    
  • Configuration class configuration, local configuration

    @FeignClient(name = "zm-teachers",configuration = FeignConfig.class)
    public interface TeacherClient {
          
          
    }
    
    public class FeignConfig {
          
          
       //日志级别
        @Bean
        public Logger.Level feignLoggerLevel(){
          
          
            return Logger.Level.FULL;
        }
    }
    
  • Configuration file configuration, global configuration

    feign.client.config.default.loggerLevel:FULL
    
  • Configuration file configuration, local configuration

    feign.client.config.zm-teachers.loggerLevel:FULL
    

3. Communication components

  • OkHttp

    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-okhttp</artifactId>
    </dependency>
    
    feign.okhttp.enabled:true
    
  • HttpClient

    <dependency>
       <groupId>io.github.openfeign</groupId>
       <artifactId>feign-httpclient</artifactId>
    </dependency>
    
    feign.httpclient.enabled:true
    

4. Gzip compression

Data length limits for GET requests and POST requests

Theoretically, there is no limit to the data length of GET requests and POST requests, but servers and browsers will limit them.

  • Browser restrictions: In order to be compatible with the length requests of various browsers, the URL length is limited to [2083] characters. (IE: 2083, Firefox: 65536, Chrome: 8182)
  • Server limitations:
    • tomecat:maxHttpHeaderSize parameter
    • nginx:large_client_header_buffers参数

feign data compression configuration

#开启feign请求压缩,默认不开始
feign.compression.reqest.enabled:true
#配置支持压缩的MIME TYPE,默认为:text/xml,application/xml,application/json
feign.compression.reqest.mime-types:text/xml,application/xml,application/json
#触发请求数据压缩的最小Size,默认2048KB
feign.compression.reqest.min-request-size: 2048

#开启Feign响应压缩,默认不开启
feign.compression.response.enabled:true
#使用GZip解码器,默认不使用
feign.compression.response.useGzipDecoder:true

Data compression places a burden on the CPU

Note, if the communication component uses okhttp3, Gzip will not take effect.

/*
 * Copyright 2013-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.openfeign.encoding;

import feign.Client;
import feign.Feign;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Configures the Feign response compression.
 *
 * @author Jakub Narloch
 * @see FeignAcceptGzipEncodingInterceptor
 */
@Configuration
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(Client.class)
@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false)
//The OK HTTP client uses "transparent" compression.
//If the accept-encoding header is present it disable transparent compression
@ConditionalOnMissingBean(type = "okhttp3.OkHttpClient")
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignAcceptGzipEncodingAutoConfiguration {
    
    

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

5. Load balancing

Load balancing configuration

zm-teachers.ribbon.NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule
zm-teachers.ribbon.ConnectTimeout: 250                 # 连接超时时间
zm-teachers.ribbon. ReadTimeout: 1000                   # ribbon 读取超时时间
zm-teachers.ribbon. OkToRetryOnAllOperations: true      # 是否对所有操作都进行重试
zm-teachers.ribbon.MaxAutoRetriesNextServer: 1         # 切换实例的重试次数
zm-teachers.ribbon.MaxAutoRetries: 1                   # 对当前实例的重试次数
Load balancing strategy illustrate
Weight strategy/WeightedResponseTimeRule A weight is assigned based on the response time of each service provider. The longer the response time, the smaller the weight, and the lower the possibility of being selected. Implementation principle: Just start using the polling strategy and start a timer, collect the average response time provided by all services at regular intervals, and then attach a weight to each service provider. The higher the weight, the greater the probability of being selected. big.
Minimum number of connections strategy/BestAvailableRule Also called the minimum concurrency strategy, it traverses the service provider list and selects a service instance with the smallest number of connections. If there are the same minimum number of connections, the polling strategy will be called for selection.
Zone Sensitivity Policy/ZoneAvoidanceRule Service instances are selected based on the performance of the region where the service is located and the availability of the service. In an environment without a region, the change strategy is similar to the polling strategy.
Available Sensitivity Policy/AvailabilityFilteringRule First filter out unhealthy service instances, and then select service instances with a smaller number of connections.
Random Strategy/RandomRule Randomly select a service instance from the list of service providers
Retry strategy/RetryRule Obtain the service according to the polling policy. If the obtained service is null or has expired, retry to obtain the service within the specified time. If the service instance is still not obtained after the specified time, null is returned.

6. Hystrix

Problems faced by complex distributed services: service avalanche

Methods to solve service avalanche: downgrade, isolation, circuit breaker, request caching, request merging.

<dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

Two ways of Hystrix callback:

  1. fallback
@FeignClient(name = "zm-biz-import-service"fallback = ImportClientHystrix.class)
public interface ImportClient {
    
    
    @RequestMapping(method = RequestMethod.POST, path = "/upload/single/file" ,produces = {
    
    MediaType.APPLICATION_JSON_UTF8_VALUE}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    Result<TeacherUploadDto> uploadSingleFile(MultipartFile  param);
}

@Component
public class ImportClientHystrix implements ImportClient {
    
    

    @Override
    public Result<TeacherUploadDto> uploadSingleFile(MultipartFile param) {
    
    
        log.warn("ImportClientHystrix uploadSingleFile error ");
        return Result.error();
    }
}
  1. fallbackFactory
@FeignClient(name = "zmbiz-asset-query", fallbackFactory = AssetQueryFeignClientFallbackFactory.class)
public interface AssetQueryFeignClient {
    
    

    /**
     * @return 根据学生ID查询student_money
     * @param
     * @return
     */
    @GetMapping(value = "/api/studentMoney/queryByStuId")
    HaloResult<List<StudentMoneyDTO>> queryStudentMoneyByStuId(@RequestParam(value = "stuId") Integer stuId);
}

@Component
@Slf4j
public class AssetQueryFeignClientFallbackFactory implements FallbackFactory<AssetQueryFeignClient> {
    
    
    @Override
    public AssetQueryFeignClient create(Throwable cause) {
    
    
        return new AssetQueryFeignClient() {
    
    
            @Override
            public Result<User> addPerson(User user) {
    
    
                log.warn("调用zmbiz-user-business服务调用异常,uri = /tBsPerson/add/person, para = {}, e = {}", JSONObject.toJSONString(user), ExceptionUtils.getFullStackTrace(e));
                return Result.errorMessage("亲,服务器升级中,请稍后再试!");
            }
        };
    }
}

It is recommended to use fallbackFactory. You can check the cause of the problem by printing downgrade exceptions.

hystrix configuration

feign.hystrix.enabled:true

#方案一:配置核心线程数量,以及最大线程数量

hystrix.threadpool.default.coreSize = 50
hystrix.threadpool.default.maximumSize = 100
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize = true

#方案二:配置队列长度以及拒绝长度

hystrix.threadpool.default.maxQueueSize: 1000 #BlockingQueue的最大队列数,默认值-1
hystrix.threadpool.default.queueSizeRejectionThreshold: 800 #即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5

Guess you like

Origin blog.csdn.net/baidu_41934937/article/details/131163897