SpringBoot e-commerce project mall (20k+star) address: https://github.com/macrozheng/mall
abstract
Spring Cloud OpenFeign is a declarative service invocation tool, which integrates Ribbon and Hystrix and has load balancing and service fault tolerance functions. This article will introduce its usage in detail.
Feign introduction
Feign is a declarative service invocation tool. We can invoke a service interface by creating an interface and configuring it with annotations, which simplifies the development of invoking a service interface directly using RestTemplate. Feign has pluggable annotation support, as well as support for Feign annotations, JAX-RS annotations and Spring Mvc annotations. When using Feign, Spring Cloud integrates Ribbon and Eureka to provide load-balanced service invocation and Hystrix-based service fault-tolerant protection.
Create a feign-service module
Here we create a feign-service module to demonstrate the common functions of feign.
Adding dependencies to pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Configuration in application.yml
server: port: 8701 spring: application: name: feign-service eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:8001/eureka/
Add the @EnableFeignClients annotation on the startup class to enable Feign's client functionality
@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class FeignServiceApplication { public static void main(String[] args) { SpringApplication.run(FeignServiceApplication.class, args); } }
Adding UserService Interface to Complete Interface Binding of UserService Service Service
We implemented a Feign client through the @FeignClient annotation, in which the value is user-service, which means that this is the interface calling client for the user-service service. We can recall the User Controller in user-service, just change it to an interface and keep the original Spring Mvc annotation.
/** * Created by macro on 2019/9/5. */ @FeignClient(value = "user-service") public interface UserService { @PostMapping("/user/create") CommonResult create(@RequestBody User user); @GetMapping("/user/{id}") CommonResult<User> getUser(@PathVariable Long id); @GetMapping("/user/getByUsername") CommonResult<User> getByUsername(@RequestParam String username); @PostMapping("/user/update") CommonResult update(@RequestBody User user); @PostMapping("/user/delete/{id}") CommonResult delete(@PathVariable Long id); }
Adding UserFeignController to invoke UserService to implement service invocation
/** * Created by macro on 2019/8/29. */ @RestController @RequestMapping("/user") public class UserFeignController { @Autowired private UserService userService; @GetMapping("/{id}") public CommonResult getUser(@PathVariable Long id) { return userService.getUser(id); } @GetMapping("/getByUsername") public CommonResult getByUsername(@RequestParam String username) { return userService.getByUsername(username); } @PostMapping("/create") public CommonResult create(@RequestBody User user) { return userService.create(user); } @PostMapping("/update") public CommonResult update(@RequestBody User user) { return userService.update(user); } @PostMapping("/delete/{id}") public CommonResult delete(@PathVariable Long id) { return userService.delete(id); } }
Demonstration of Load Balancing Function
- Start eureka-service, two user-service and feign-service services. After startup, the registry is shown as follows:
- Multiple calls http://localhost:8701/user/1 Tests show that user-service services running in 8201 and 8202 alternately print the following information:
2019-10-04 15:15:34.829 INFO 9236 - - [nio-8201-exec-5] c.macro.cloud.controller.UserController: Get user information according to id, user name is macro: 2019-10-04 15:15:35.492 INFO 9236 - - [io-8201-exec-10] c.macro.cloud.controller.UserController: Get user information according to id, user name is macro: 2019-10-04 15:15:35.825 INFO 9236 - - [nio-8201-exec-9] c.macro.cloud.controller.UserController: Get user information according to id, user name is macro:
Service degradation in Feign
Service degradation in Feign is very convenient to use. Just add an implementation class for service degradation processing to the interface defined by Feign client. Next, we add a service degradation implementation class for UserService interface.
Adding the Service Degradation Implementation Class UserFallbackService
It should be noted that it implements the UserService interface and implements the service degrading logic for each implementation method in the interface.
/** * Created by macro on 2019/9/5. */ @Component public class UserFallbackService implements UserService { @Override public CommonResult create(User user) { User defaultUser = new User(-1L, "defaultUser", "123456"); return new CommonResult<>(defaultUser); } @Override public CommonResult<User> getUser(Long id) { User defaultUser = new User(-1L, "defaultUser", "123456"); return new CommonResult<>(defaultUser); } @Override public CommonResult<User> getByUsername(String username) { User defaultUser = new User(-1L, "defaultUser", "123456"); return new CommonResult<>(defaultUser); } @Override public CommonResult update(User user) { return new CommonResult("The call failed and the service was degraded",500); } @Override public CommonResult delete(Long id) { return new CommonResult("The call failed and the service was degraded",500); } }
Modify the UserService interface and set the service degradation processing class to UserFallbackService
Modify the parameters in the @FeignClient annotation and set fallback to UserFallbackService.class.
@FeignClient(value = "user-service",fallback = UserFallbackService.class) public interface UserService { }
Modify application.yml to turn on Hystrix functionality
feign: hystrix: enabled: true #Open Hystrix in Feign
Demonstration of Service Degradation Function
- Close two user-service services and restart feign-service;
- call http://localhost:8701/user/1 Testing shows that service degradation information is returned.
Log Printing Function
Feign provides logging printing, and we can adjust the log level by configuring it to understand the details of Http requests in Feign.
log level
- NONE: By default, no logs are displayed;
- BASIC: Only request method, URL, response status code and execution time are recorded.
- HEADERS: In addition to the information defined in BASIC, there are headers for requests and responses.
- FULL: In addition to the information defined in HEADERS, there are also the body and metadata of requests and responses.
Open more detailed logs through configuration
We use the java configuration to enable Feign to print the most detailed Http request log information.
/** * Created by macro on 2019/9/5. */ @Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
Configure the Feign client that needs to open the log in application.yml
The log level for configuring UserService is debug.
logging: level: com.macro.cloud.service.UserService: debug
view log
call http://localhost:8701/user/1 For testing, you can see the following logs.
2019-10-04 15:44:03.248 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] ---> GET http://user-service/user/1 HTTP/1.1 2019-10-04 15:44:03.248 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] ---> END HTTP (0-byte body) 2019-10-04 15:44:03.257 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] <--- HTTP/1.1 200 (9ms) 2019-10-04 15:44:03.257 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] content-type: application/json;charset=UTF-8 2019-10-04 15:44:03.258 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] date: Fri, 04 Oct 2019 07:44:03 GMT 2019-10-04 15:44:03.258 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] transfer-encoding: chunked 2019-10-04 15:44:03.258 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] 2019-10-04 15:44:03.258 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#GetUser] {"data": {"id": 1, "username", "macro", "password", "123456"}, "message", "operation success", "code":200} 2019-10-04 15:44:03.258 DEBUG 5204 --- [-user-service-2] com.macro.cloud.service.UserService : [UserService#getUser] <--- END HTTP (92-byte body)
Common configuration of Feign
Feign's own configuration
feign: hystrix: enabled: true #Open Hystrix in Feign compression: request: enabled: false #Whether GZIP compression is applied to requests mime-types: text/xml,application/xml,application/json #Specify the compressed request data type min-request-size: 2048 #Requests that exceed this size are compressed response: enabled: false #Whether to Compress the Response with GZIP logging: level: #Modify Log Level com.macro.cloud.service.UserService: debug
Ribbon configuration in Feign
Configuring Ribbon in Feign can directly use Ribbon's configuration for reference. Spring Cloud Ribbon: Load-balanced service invocation.
Hystrix configuration in Feign
Configuring Hystrix in Feign can directly use the configuration of Hystrix for reference. Spring Cloud Hystrix: Service Fault Tolerant Protection.
Modules used
springcloud-learning ├── eureka-server -- eureka Registry Center ├── user-service -- provide User object CRUD Interface services └── feign-service -- feign Service invocation test service
Project source address
https://github.com/macrozheng/springcloud-learning
Public address
mall project In the whole series of learning courses, we pay attention to the first time acquisition of the public number.