Spring Cloud entry service calls OpenFeign

Spring Cloud 之 OpenFeign

1. Introduction to Feign

  Spring Cloud OpenFeign is a set of declarative and templated service call clients based on Netflix Feign. Feign can help us call HTTP API more quickly and elegantly. It makes it easier to write web service clients. We only need to create the interface and configure it with annotations to complete the binding of the Web service interface. It has pluggable annotation support, including Feign annotations and JAX-RS annotations. It also supports pluggable encoders and decoders. Spring Cloud Feign also extends the support for Spring MVC annotations, and also integrates Ribbon and Eureka to provide a balanced load HTTP client implementation.

Official document: "Declarative REST Client: Feign" .

2. Simple to use

  In the previous study of "Eureka Registry" and "Client Load Balancing", we have been using RestTemplate to call the service interface. At this time, we need to know the specific information of the service interface, such as: IP address or service name, port number, Interface address, etc., this kind of mobilization using the approximate original Http method has brought a lot of complexity for us to write code. Feign encapsulates these details and provides us with a faster and more elegant way to call HTTP API. Let's wait and see:

1. Build a Feign-based consumer client

  The registration center and service provider can use the application in the previous example, here only need to reconstruct the consumer reference, because Feign itself is to simplify the HTTP encapsulation of the consumer service interface written by the developer.

2. Introduce Feign dependency

  On the basis of the original consumption, just add Feign related dependencies, as follows:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>
3. Turn on Feign function

  Enabling the Feign function is very simple. You only need to add the @EnableFeignClients annotation interface to the startup class to start the Feign function.

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EurekaConsumerApplication {

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

}
4. Define Feign interface

  Defining the Feign interface is a very important and basic work for implementing Feign invocation. Feign implements the invocation of the service interface according to the defined interface and the annotations therein. At the same time, the current application only needs to call the corresponding method like a local class.

@FeignClient("eureka-provider")
public interface FeignApiClient {

    @GetMapping("/provider")
    String provider();
    
}

  In the above code, the @FeignClient annotation target is on the interface, which is used to indicate that the interface is used as a FeignClient, and the value indicates the name of FeignClient (if the service registry is used, the name of the service provider is generally used), if The project uses Ribbon, and the value attribute will be used as the name of the microservice for service discovery. The @GetMapping annotation is mainly used to specify the HTTP API in the corresponding service provider, that is, when the method is called, the address of the service provider is actually called.

5. Write consumer Controller

  Here we only need to define an ordinary Controller class, in which we need to inject the Feign interface class FeignApiClient defined earlier into this class. At this time, we can call the interface designation just like using ordinary service classes. Way out.

@RestController
public class FeignController {

    Logger logger = Logger.getLogger(FeignController.class);

    @Autowired
    private FeignApiClient feignApiClient;

    @RequestMapping("/feignApi")
    public String feignApi(){
        logger.info("执行消费者FeignController的feignApi()方法!");
        return feignApiClient.provider();
    }
}
6. Start and verify

  Start the application and visit http://localhost:8020/feignApi after normal startup. At this time, the service provider's interface is called normally, and the consumer returns the correct information. At this time, we have completed the simple example of Feign. Here we simply construct a Feign-based consumer. Let's try some other usages.

3. Feign log level

3.1. Log configuration of a single service

  Enabling Feign log configuration requires two steps:

  The first step is to add relevant configuration to the configuration file application.properties:

# 启用Feign日志级别
logging.level.com.qriver.cloud.consumer.feign.FeignApiClient: DEBUG

  Among them, logging.level is a fixed prefix, com.qriver.cloud.consumer.feign.FeignApiClient is the permission class name of the corresponding Feign interface, and the corresponding Value can only be of type DEBUG.

  The second step is to increase the configuration class of Feign log or increase the corresponding configuration.

  If you use the configuration file format, add the following configuration to the configuration file application.properties, where feign.client.config is a fixed format, eureka-provider is the application name of the service provider, logger-level is a fixed format, full is optional Log level.

feign.client.config.eureka-provider.logger-level: full

  If you choose to increase the configuration class of Feign logs, the code is as follows:

@Configuration
public class FeignLoggingConfig {

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

  In the above configuration class, we use the FULL level log. Regardless of whether the configuration file or the configuration class is used, this is configured for each microservice service provider.

3.2, global log configuration

  When Feign logs are configured globally, two steps are also required:

  The first step is to define where the log needs to be output. This is the same as the normal log method in java web, that is, configure the package configuration that needs to print the log.

# 启用Feign日志级别
logging.level.com.qriver.cloud.consumer.feign.*: DEBUG

  The second step is to add Feign global log configuration, similar to single service configuration, there are also two ways of configuration class and configuration file.

  If you use the configuration file method, you only need to add the following configuration to the configuration file:

feign.client.config.default.logger-level: full

Compared with the log configuration of a single service provider, here you can change the service name to default.

  If you choose to use the configuration class, the definition method of the configuration class is the same as the configuration class defined for a single service. You only need to remove the @Configuration annotation and it will not be posted again here. To import the global log configuration, you need to modify the annotation @EnableFeignClients to enable Feign, add the defaultConfiguration attribute, and import the configuration class. The code is as follows:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(defaultConfiguration = FeignLoggingConfig.class)
public class EurekaConsumerApplication {

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

}
3.3, Feign log level

  Feign has four levels of logs, namely:

  1. NONE: Do not record any log information, this is the default value.
  2. BASIC: It only records the request method, URL and response status and execution time, similar to Tomcat's default access log.
  3. HEADERS: On the basis of BASIC, the header information of the request and response is additionally recorded
  4. FULL: Records the details of all requests and responses, including header information, request body, and metadata.

  Below are four examples of logs printed at different levels:

FULL level:

2020-11-08 14:53:07.697  INFO 2504 --- [nio-8020-exec-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:1;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@66e383de
2020-11-08 14:53:07.830 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] <--- HTTP/1.1 200 (490ms)
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] connection: keep-alive
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] content-length: 12
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] content-type: text/plain;charset=UTF-8
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] date: Sun, 08 Nov 2020 06:53:07 GMT
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] keep-alive: timeout=60
2020-11-08 14:53:07.831 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] 
2020-11-08 14:53:07.833 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] Hello World!
2020-11-08 14:53:07.834 DEBUG 2504 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] <--- END HTTP (12-byte body)
2020-11-08 14:53:08.661  INFO 2504 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

HEADERS level:

2020-11-08 14:55:45.091  INFO 10800 --- [nio-8020-exec-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:1;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@7e8dcbf2
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] <--- HTTP/1.1 200 (375ms)
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] connection: keep-alive
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] content-length: 12
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] content-type: text/plain;charset=UTF-8
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] date: Sun, 08 Nov 2020 06:55:45 GMT
2020-11-08 14:55:45.179 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] keep-alive: timeout=60
2020-11-08 14:55:45.180 DEBUG 10800 --- [nio-8020-exec-1] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] <--- END HTTP (12-byte body)
2020-11-08 14:55:46.061  INFO 10800 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

BASIC level:

2020-11-08 14:59:01.149  INFO 94780 --- [nio-8020-exec-2] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:1;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@23aa7540
2020-11-08 14:59:01.239 DEBUG 94780 --- [nio-8020-exec-2] c.q.cloud.consumer.feign.FeignApiClient  : [FeignApiClient#provider] <--- HTTP/1.1 200 (393ms)
2020-11-08 14:59:02.117  INFO 94780 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

NONE level:

2020-11-08 15:00:40.790  INFO 44616 --- [nio-8020-exec-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client eureka-provider initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-provider,current list of Servers=[localhost:8010],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:1;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},Server stats: [[Server:localhost:8010;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@739c9f13
2020-11-08 15:00:41.759  INFO 44616 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: eureka-provider.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

4. Compress request and response data

  In order to improve the transmission efficiency of request data and response data in the network, Feign provides a compression function for request and response data. The opening method is as follows:

feign.compression.request.enabled=true
feign.compression.response.enabled=true

  Those requests or responses can be compressed? Feign provides two strategies, the first is based on the type of multimedia, the second is based on the size of the request, the specific configuration is as follows:

feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

5. Ribbon-based load balancing

  Feign realizes Ribbon-based load balancing is very easy. First of all, you need to import Ribbon's dependency files, as shown below:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>

  Then, when defining the Feign interface, @FeignClient annotates the name or value attribute to use the service name (just do not bind the specific instance address).

5.1. Prepare the environment

  Verify that the required environment is the same as that in "Client Load Balancing", and then reconstruct the consumer, and the consumer only needs to introduce the ribbon dependency, and Feign will automatically enable the load balancing mechanism.

5.2, verification

  After starting, after accessing the interface multiple times, you will find that the service providers are evenly distributed to the two services, indicating that the load balancing has taken effect. Here is just a simple realization of load balancing, we will analyze how they work in detail later.

Guess you like

Origin blog.csdn.net/hou_ge/article/details/111537931