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