Using feign as the client to call remote http service in spring boot

Feign introduction

A central concept supported by feign of pring Cloud is named client Feign client uses @ feign client to register and assemble components and call remote server on demand
Spring Cloud uses FeignClientsConfiguration to create a new collection as the ApplicationContext (application context) of each named client, including feign Decoder,feign.Encoder and feign Contract. Feign works by injecting a templating request with annotations. Just close it before sending, and the parameters can be directly applied to the template. However, this also limits feign, which only supports text API, which greatly simplifies the system in response to requests

feign template embodiment

When the Spring Cloud application starts, feign will scan the interface marked with @ FeignClient annotation, generate a proxy, and register it in the Spring container. When generating the proxy, feign will create a requesttemplate object for each interface method, which encapsulates all the information required by the HTTP request. The request parameter name, request method and other information are determined in this process. Feign's templating is reflected here.

Function realization

Introduce dependency

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

Client interface

@FeignClient(name = "cdkClient",contextId = "cdk-client",path = "/act/test",
            url ="${setting.bigScreen.host}",
                fallback = CilentErr.class)
public interface CilentApi {

    @PostMapping("/feignTest")
    public void cilentTest(@RequestBody String code);

The value of name is: the name of the calling client.
url: a separate http interface. The interface provider does not register with the registration center and makes remote calls through the http request path
Path: the interface path of the call
fallback: exception handling, which is executed when the service call fails

Feign serializes the method parameter object in the method signature into the request parameter and puts it into the HTTP request, which is completed by the encoder. Similarly, the deserialization of HTTP response data into java objects is completed by the decoder. By default, feign will convert the parameters marked with @ RequestParam annotation into strings and add them to the URL, and convert the parameters without annotation into json through Jackson and put them in the request body. Note that if the method in @ RequetMapping specifies the request mode as POST, all parameters without annotation will be ignored

Server interface

@RestController
@RequestMapping("/act/test")
@Slf4j
public class CdServcieController {

    @PostMapping("/feignTest")
    public void cilentTest(@RequestBody String code){
        log.info("Service port received request"+code);
    };
}

feign uses Hystrix

Introduce dependency

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

Class in client fallback

@Component
public class CilentErr implements CilentApi {
    @Override
    public void Test1(String code) {
        System.out.println("Called when the service fails");
    }
}

Then add @ EnableFeignClients on the startup class,
@Enablercircuitbreaker annotation

Final configuration file

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
#Whether to print the SQL generated by JPA execution on the console
spring.jpa.show-sql=true 
#Indicates that the database corresponding to JPA is MySQL
spring.jpa.database=mysql
#Indicates that the table in the database is updated according to the entity class when the project is started
spring.jpa.hibernate.ddl-auto=update
#Indicates that the database dialect used is MySQL57Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
server.port=8071
setting.bigScreen.host=http://localhost:8091
#Open hystrix
feign.hystrix.enabled=true


In Spring Cloud, Feign and Ribbon may fail to call for the first time after integrating Hystrix. How to solve this problem?
The default timeout of Hystrix is 1 second. If there is no response after this time, it will enter the fallback code.
The first request is often slow (because Spring's lazy loading mechanism needs to instantiate some classes), and the response time may be more than 1 second.
Solution:
Method 1
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
This configuration changes the timeout of Hystrix to 5 seconds
Method 2
hystrix.command.default.execution.timeout.enabled: false
This configuration is used to disable the timeout of Hystrix

Extended configuration of feign

#Hystrix support. If true, the hystrix library must be in the classpath
feign.hystrix.enabled=false

#Request and response GZIP compression support
feign.compression.request.enabled=true
feign.compression.response.enabled=true
#Support compressed mime types
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
# Log support
logging.level.project.user.UserClient: DEBUG

Brief introduction of feign principle
1 when the spring cloud application starts, the program will scan the package, scan all interfaces marked with @ FeignClient annotation under all packages, generate proxy objects, and inject these interfaces into the IOC container of spring

2 when the interface in the defined Feign is called, the RequestTemplate proxy object is generated through the dynamic proxy of JDK.
This object encapsulates all the information required by the HTTP request. The request parameter name, request method and other information are determined in this process. Feign's templating is reflected here

3. The requesttemplate is regenerated into a Request.

4 then submit the Request to the client for processing. By default, this client is the HttpUrlConnection of JDK (it can also be HttpClient or Okhttp, which needs to be configured)

5 Finally, the Client is encapsulated into the LoadBalanceClient class, which combines the Ribbon class to achieve load balancing

Keywords: Java Spring Spring Boot http

Added by imcookie on Thu, 17 Feb 2022 21:28:06 +0200