Note: the following is the text of this article. The following cases are for reference
1, Why learn OpenFeign?
- Previously, we used to call RestTemplate to realize remote calling. There is a problem with using RestTemplate: it is cumbersome. Each request is the same except for different parameters, different request addresses and different returned data. Therefore, we hope to simplify it. The simplified solution is OpenFeign.
- OpenFeign is a declarative calling component developed by the Spring cloud team on the basis of Netflix Feign
2, Introduction and difference between OpenFeign and Feign
1. What is feign
Feign Is a declarative WebService client. use Feign Enables writing Web Service The client is simpler. Feign Integrated Ribbon,RestTemplate The implementation of load balancing is realized Http Call, only for the original method( Ribbon+RestTemplate)Encapsulated, developers do not need to manually use RestTemplate Instead of calling a service, you define an interface, and you can complete the service call by marking an annotation on this interface. This is more in line with the purpose of interface oriented programming and simplifies the development.
2. What is openfeign
OpenFeign yes springcloud stay Feign On the basis of SpringMVC Notes for, such as@RequestMapping wait. OpenFeign of@FeignClient Can be resolved SpringMVC of@RequestMapping Annotate the interface, and generate the implementation class through dynamic proxy, load balance and call other services in the implementation class.
OpenFeign's official website address: https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/
Git address of OpenFeign: https://github.com/spring-cloud/spring-cloud-openfeign
3. Differences between feign and OpenFeign
3, OpenFeign service call
The service provider still pays for the service with the previous 8001 and 8002
1. Create the cloud consumer feign order80 consumer module
2. Change pom file
<dependencies> <!--openfeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- Introduce self-defined api General package, which can be used Payment payment Entity --> <dependency> <groupId>com.heng</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <!--web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--General basic general configuration--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
3. Building yml
server: port: 80 spring: application: name: cloud-feign-order-service eureka: client: #Indicates whether to register yourself with Eurekaserver. The default value is true. register-with-eureka: true #Whether to retrieve the existing registration information from EurekaServer. The default value is true. A single node does not matter. The cluster must be set to true to use load balancing with ribbon fetchRegistry: true service-url: defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
4. Main startup
package com.heng; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableFeignClients public class OrderFeignMain80 { public static void main(String[] args) { SpringApplication.run(OrderFeignMain80.class,args); } }
Add @ EnableFeignClients annotation to enable OpenFeign support
5. Write the business logic interface and use @ FeignClient
package com.heng.service; import com.heng.entities.CommonResult; import com.heng.entities.Payment; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @Component @FeignClient(value ="CLOUD-PAYMENT-SERVICE") public interface PaymentFeignService { @GetMapping(value = "/payment/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id); }
6. Write controller class
@RestController @Slf4j public class OrderFeignController { @Resource private PaymentFeignService paymentFeignService; @GetMapping(value = "/consumer/payment/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) { return paymentFeignService.getPaymentById(id); } }
Test:
Note: the method suggestion of the interface is consistent with the method of the service provider
4, OpenFeign timeout control
Test OpenFeign timeout control by writing a delay program
- Service provider 8001 / 8002 intentionally writes suspension procedures
@GetMapping(value = "/payment/feign/timeout") public String paymentFeignTimeout() { // Business logic processing is correct, but it takes 3 seconds try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return serverPort; }
- The service consumer 80 adds a timeout method
@Component @FeignClient(value ="CLOUD-PAYMENT-SERVICE") public interface PaymentFeignService { @GetMapping(value = "/payment/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id); @GetMapping(value = "/payment/feign/timeout") public String paymentFeignTimeout(); }
- The controller writes the calling method
@GetMapping(value = "/consumer/payment/feign/timeout") public String paymentFeignTimeout() { // The OpenFeign client generally waits for 1 second by default return paymentFeignService.paymentFeignTimeout(); }
- test
http://localhost/consumer/payment/feign/timeout
OpenFeign waits for 1 second by default, and an error will be reported after the delay
Control the timeout of OpenFeign client by modifying the configuration file
#Set feign client timeout (ribbon is supported by OpenFeign by default) (unit: ms) ribbon: #It refers to the time taken to establish a connection. It is applicable to the time taken to connect both ends under normal network conditions ReadTimeout: 5000 #It refers to the time taken to read the available resources from the server after the connection is established ConnectTimeout: 5000
Revisit
5, OpenFeign log enhancement
Feign The log printing function is provided. We can adjust the daily fault level through configuration to understand Feign in Http Details of the request. yes Feign Monitor and output the calling status of the interface
Log level:
- NONE: default, no logs are displayed;
- BASIC: only record the request method, URL, response status code and execution time;
- HEADERS: in addition to the information defined in BASIC, there are also header information of request and response;
- FULL: in addition to the information defined in HEADERS, there are also the body and metadata of the request and response.
1. Write a configuration class to set the log level
package com.heng.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
2. Modify the yml file to open the Feign client of the log
logging: level: com.heng.service.PaymentFeignService: debug
When we initiate a request, we can see the request and response text in the background log
The entire moudle directory consists of: