Spring Cloud (12) Infamous service invocation: use of feign (bottom)

Source: Internet
Author: User

Objective

This article is an extension of the previous blog, a lot of the usual features will begin to write a brief, Spring cloud version of the gap between the large, less than the possibility of the next version is killed. As the author of this article began to misunderstand the feign inheritance characteristics, leading to the experiment did not succeed, today is the Saturday overtime in the process of drawing a figure, reference to some information to get the correct results, I am learning while writing blog to do verification, update estimate is not fast ... Not much to say, continue to feign study.

V. Characteristics of inheritance

We find that every time we define feign to invoke the interface of the service provider, we have to write a copy of the interface with the same interface method name parameter list as the call, so is there a way to directly use feign to invoke the interface of the service provider without writing these interfaces? The answer is the feign inheritance that I bring to you in this section, the structure is basically as follows:

Paste the structure diagram of the service provider project

First, in order to facilitate the separation of the previous interface, we create a package in the service provider Project interfaces , create the interface we want to use in the package, the code

Package com.cnblogs.hellxz.interfaces;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;/*** <b> class name </b>: HelloService* <p><b> description </b>: Interface for defining controller, implementation placed in controller* The main function of this class is to facilitate the testing of inheritance characteristics in feign* </p> ** <p><b> Created date </b> 2018/6/23 11:43 </p>* @author hellxz Zhang* @version 1.0* @since JDK 1.8 */Public interface HelloService {    /*** Declaration of an interface, not implemented     */@GetMapping (value = "/refactor-service/{name}")string Hello (@PathVariable ("name") string name);}

Points to note in the above code:

  1. We will think of feign client will inherit this interface, feign can not have @GetMapping such a combination of annotations, then in this interface should we also write @RequestMapping and specify the request method? After I have measured, it is not necessary. This is exactly what SPRINGMVC does here.
  2. This is an interface class, not implemented

The interface above is not implemented, so I controller provide it with an implementation class in the package

Package Com.cnblogs.hellxz.controller;import Com.cnblogs.hellxz.interfaces.HelloService;import Org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.PathVariable;import Org.springframework.web.bind.annotation.RestController;/*** Controller that implements the HelloService interface */@RestController //You must add this note to tell Springmvc that this is a controller Public classHelloserviceimplcontrollerImplementsHelloService {Private FinalLogger Logger = loggerfactory.GetLogger(Helloserviceimplcontroller.class);/*** Implement the Hello method in HelloService, this method to return the result     */    @Override     PublicStringHello(@PathVariableString name) {logger.Info("Refactorhelloservice's Hello Method executed, enter parameter: name:{}", name);return "Hello,"+name; }}

The above code should be noted that:

  1. @RestController annotations must be added
  2. When overriding the method of the interface, @GetMapping such as the URL and so do not write
  3. The parameter annotation in the method is still to write, otherwise it will not receive parameters, I have to troubleshoot this issue to print the log, as in the last code block @PathVariable is to get the parameters of the

Now we install the service provider mvn install into the local repository so that we can rely on the service provider in other projects

Next, we dependencies add the dependency of the service provider in the Feigncustomer of the POM node of this project

        <!--添加服务提供者的依赖-->        <dependency>            <groupId>com.cnblogs.hellxz</groupId>            <artifactId>EurekaServiceProvider</artifactId>            <version>0.0.1-SNAPSHOT</version>        </dependency>

To do this, we also need a feign client to invoke the service provider's service, which is not the same as the method we used earlier, the code is as follows:

package com.cnblogs.hellxz.client;import com.cnblogs.hellxz.interfaces.HelloService;import org.springframework.cloud.netflix.feign.FeignClient;/** * 继承服务提供者的HelloService的接口,从而拥有这个接口的所有方法 * 那么在这个Feign中就只需要使用HelloService定义的接口方法 */@FeignClient("eureka-service")publicinterfaceextends HelloService {}

Attention:

  1. Here we do not need to rewrite the interface to implement HelloService
  2. With the extends keyword, instead of implements, the implements will require you to implement

Next we HelloController inject the upper feign in and add the call controller, omitting the previous code

    //省略类头    @Autowired    private RefactorHelloServiceFeign refactorHelloServiceFeign;    //省略其它Controller方法    /**     * 测试Feign的继承特性     */    @GetMapping("/refactor/{name}")    @ResponseBody    publicrefactorHelloService(@PathVariable String name){        return refactorHelloServiceFeign.hello(name);    }

Test this controller with postman.

2. Pros and cons

Pros: No need to rewrite methods to invoke in definition feign, reduce effort, and code is more flexible

Disadvantage: More code coupling, need more stringent specifications, otherwise interface changes prone to reaching, thereby increasing maintenance difficulty

Six, ribbon Configuration

The spring cloud feign load balancer is implemented through the spring cloud ribbon, and when we use it for @FeignClient(value="eureka-service") the feign interface, not only did we create the feign client, but we also created a name called "Eureka-service "The Ribbon, the client.

With this in mind, we can implement the configuration of the Ribbon in a custom feign by adding the specified parameters to the configuration file

The following ribbon configuration is not reflected in the code

1. Global configuration

ribbon.<key>=<value>the way to modify the global default configuration

Example (YML):
ribbon:  # 同一实例最大重试次数,不包括首次调用  MaxAutoRetries: 1  # 重试其他实例的最大重试次数,不包括首次所选的server  MaxAutoRetriesNextServer: 2  # 是否所有操作都进行重试  OkToRetryOnAllOperations: false
2. Specify the service configuration

Modify the configuration of the <client>.ribbon.<key>=<value> specified service by the way

Example (properties)
eureka-service.ribbon.ConnectTimeout=500eureka-service.ribbon.ReadTimeout=2000eureka-service.ribbon.OkToRetryOnAllOperations=trueeureka-service.ribbon.MaxAutoRetriesNextServer=2eureka-service.ribbon.MaxAutoRetries=1

The Eureka-service used is the name of the service to be configured

Seven, retry mechanism

Spring Cloud feign defaults to the retry mechanism (internally also the Ribbon retries), when a service provider is requested, and the service provider does not return a result within the feign delay time, then feign will initiate the second request by default, if it is a network problem. To make the first request fail, the second request may succeed, which enables high availability of the service. If the service provider has multiple instances, you can also give the opportunity of the second request to another instance.

We can change the retry operation by configuring the Ribbon in the previous section, for example, eureka-service.ribbon.MaxAutoRetriesNextServer=2 This configuration instruction can only be retried between two instances.
eureka-service.ribbon.MaxAutoRetries=1This configuration instruction automatically retries at most

We can design experiments:
    1. Open the service provider with a deferred method that provides the thread sleep, and let it respond much more than the Readtimout value, write the log in this method and see how many requests come in
    2. The second experiment is to start the service provider for the above experiment with two instances to view the output
Lab 1:

Add a method to the service provider GetRequestController :

    /**     * 测试Feign延迟重试的代码     * 这里我们为这个方法加上超过Feign默认2000ms以上的延迟,我们只需要通过查看日志输出即可     */    @GetMapping("/retry")    publicfeignRetry(){        logger.info("feignRetry方法调用成功");        try {            Thread.sleep(20000);        catch (InterruptedException e) {            e.printStackTrace();        }        return"ok";    }

EurekaServiceFeignAdding a method to call the top service provider in Feigncustomer

    /**     * 测试重连机制     */    @RequestMapping"/retry", method = RequestMethod.GET)    feignRetry();

HelloControlleradd a controller that calls the top method in feign

    /**     * 测试重连机制     */    @GetMapping("/retry")    @ResponseBody    publicretry(){        return eurekaServiceFeign.feignRetry();    }

In the application.yml add

ribbon:  # 同一实例最大重试次数,不包括首次调用  MaxAutoRetries: 1  # 重试其他实例的最大重试次数,不包括首次所选的server  MaxAutoRetriesNextServer: 2  # 是否所有操作都进行重试  OkToRetryOnAllOperations: false

Test 1:

Visible retry is indeed there, but this experiment is clearly set to retry only, that is, should be printed two times, in the idea of the hint can not resolve these configurations, it may be I use in the Feigncustomer Project Spring Cloud dependency is too new, this problem first put here, Because this configuration does not take effect, so the second experiment will not be done anymore ... Have to know the classmate trouble tell one or two [hands together]

Eight, hystrix configuration

Spring Cloud Feign nature is also the implementation of Hystrix, also has a circuit breaker function, here we see how to set the properties of Hystrix

1. Global configuration

hystrix.command.defaultAdd the attributes you want to configure by prefixing them, such as

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

Before configuring the Hystrix property, we want to ensure that feign.hystrix.enabled the parameter value is not false, and if false, the support to turn off the circuit breaker (Hystrix)

To turn off the fuse:hystrix.command.default.execution.timeout.enabled=false

To turn off the Hystrix feature:feign.hystrix.enabled=false

2. Disable Hystrix

In addition to the shutdown method in the global configuration, if we do not want to globally turn off hystrix support, just turn off the Hystrix feature for a client, you need to provide a configuration class for feign, as follows

package com.cnblogs.hellxz.config;import feign.Feign;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Scope;/** * 用于禁用Feign中Hystrix的配置 */publicclass DisableHystrixConfiguration {    @Bean    @Scope("prototype")    public Feign.BuilderfeignBuilder(){        return Feign.builder();    }}

In the annotations for the feign class @FeignClient , use the configuration parameter to point to the Config class you just created

@FeignClient"eureka-service",configuration = DisableHystrixConfiguration.class//其中的value的值为要调用服务的名称, configuration中配置的是禁用Feign中的Hystrix功能的类publicinterface EurekaServiceFeign {
3. Specify command configuration

Hystrix command configuration in the actual application will also be based on the actual business situation to develop a different configuration, configuration method is similar to the traditional hystrix command parameter configuration, adopted hystrix.command.<commandKey> as a prefix, 默认情况下<commandKey>会使用Feign客户端的方法名作为标识 so, Our configuration for the Hellofeign method in Eurekaservicefeign is:

hystrix.command.helloFeign.execution.isolation.thread.timeoutInMilliseconds=5000

When using the specified command configuration, it is important to note that the method name is likely to be duplicated, when the hystrix configuration of the same method name is shared, and of course you can use the overridden Feign.Builder implementation and create an instance of it in the application main class to override the implementation of the automation configuration HystrixFeign.Builder .

4. Service Downgrade configuration

Before learning the configuration of service demotion in feign, we review the annotations that the service demotion in Hystrix uses and the @HystrixCommand fallback parameter points to the downgrade method. In fact, feign is the same, the implementation is relatively simple.

Just write a class that implements the feign, @Component annotate it, and then add in each method the processing logic that you want it to fail.

Note: To note the method of shutting down hystrix that you just configured, I have commented out the code in GitHub

Look more obvious in code

New EurekaServiceFeignFallback ImplementationEurekaServiceFeign

Package com.cnblogs.hellxz.client;import Com.cnblogs.hellxz.entity.User;import org.springframework.stereotype.Component;import java.util.List;/*** Service downgrade callback class */@Component //must add this annotation, let this class as bean to spring management, otherwise will not find downgrade class Public classEurekaservicefeignfallbackImplementseurekaservicefeign{/*** This method is used only for example, return a "failure"     */    @Override     PublicStringhellofeign() {return "Failed"; }@Override     PublicStringgreetfeign(String DD) {return NULL; }@Override     PublicList<user>Getusersbyids(list<long> IDs) {return NULL; }@Override     PublicStringgetparambyheaders(String name) {return NULL; }@Override     PublicUserGetuserbyrequestbody(User user) {return NULL; }@Override     PublicStringFeignretry() {return NULL; }}

EurekaServiceFeignAdd the @FeignClient fallback parameter to the indent class you just created.

@FeignClient"eureka-service",configuration = DisableHystrixConfiguration.class, fallback = EurekaServiceFeignFallback.class)publicinterface EurekaServiceFeign {

Note: The configuration of this parameter can not be added, this is used to configure the disabled Hystrix function

Now this is configured, if the network environment is bad, the service will be degraded, because feign will automatically retry, my configuration is not effective, so there is no verification. But I often use it in my work, so that the configuration is able to achieve the degradation of the service.

Ix. other configuration 1. Request compression (feign Request/response compression)

Spring Cloud feign supports gzip compression of requests and responses to reduce bandwidth consumption during communication

Just add two lines of configuration to turn on request compression

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

There are some more detailed configurations

feign.compression.request.enabled=truefeign.compression.request.mime-types=text/xml,application/xml,application/jsonfeign.compression.request.min-request-size=2048
2. Feign log (feign logging)

When the feign log function is turned on, a logger (logger) is created for each feign client, and its name defaults to the full-scale naming of the feign interface, and the log logger can only respond to DEBUG log

Open record

Application.yml is filled with logging.level prefix, followed by the feign interface path full-scale naming

logging.level.com.cnblogs.hellxz.client.EurekaServiceFeign: DEBUG

Add the above configuration or finish, the official document says the log output level is NONE the default, we also need to configure the next

Logger.LevelThe object is configure per client, tells feign how much to log. Choices is:

  • NONE, No logging (DEFAULT).
  • BASIC, Log only the request method and URL and the response status code and execution time.
  • HEADERS, Log the basic information along with request and response headers.
  • FULL, Log the headers, body, and metadata for both requests and responses.

Under Simple translation:

    • None: Do not log any information
    • BASIC: Only the request method and URL are logged, as well as the status code and execution time
    • HEADERS: Header information for simultaneous recording of requests and responses on basic basis
    • Full: Record details of all requests and responses

We can change the log output level to complete the log output, the official website gives an example is full

@Configurationpublicclass FooConfiguration {    @Bean    Logger.LevelfeignLoggerLevel() {        return Logger.Level.FULL;    }}

In addition to using the configuration class, you can also include the

@BeanLogger.LevelfeignLoggerLevel(){    return Logger.Level.FULL;}
End

Spring Cloud Feign This part of the write here, feign easy to use, powerful, compared to hystrix implementation more dexterous, but here to say a little more, that is, if you want to a more detailed interface and high performance requirements of the case, with hystrix more suitable for some.

Originally thought feign this part not so many things, while reading, while looking at official documents, this suddenly wrote so long ...

Next, let's take a look at the API Gateway Service: Spring Cloud Zuul

This article refers to:

  1. "Spring Cloud Micro-service Combat" Suphing
  2. Official documents
This article is for the study record article, if need reprint please indicate the source

Spring Cloud (12) Infamous service invocation: use of feign (bottom)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.