What is hystrix?
hystrix is a fuse protection middleware used by netflix for microservice distributed system. hystrix provides elegant response results to clients after the service is not reachable or the request times out.
Why use hystrix?
In the microservice scenario, many services depend on each other. If the dependent services cannot be isolated, the services themselves may fail. hystrix can realize isolation between services. When a service fails, it can gracefully backoff and degrade to avoid chain reaction
hystrix quick start
Pay attention to the public number "happy code farmer" and reply to "hystrix" to get the basic item of this section.
Operate on the consumer service
Add maven dependency
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
Add annotation @ hystrixcommand on userConsumerService class (fallbackmethod = "getuserfallback")
getUserFallback is to call the method when the execution of the method times out or fails, giving an elegant response
Add corresponding method
//Failed callback
public User getUserFallback(@RequestParam("name") String name){
User user=new User();
user.setName(name);
user.setEmail("Call failed");
return user;
}
In order to verify the effect, this time we start the eurek and consumer projects, and make the product service directly unable to adjust, to simulate the request timeout. This is a separate use of hystrix for fusing degradation. Next, we will introduce the combination of hystrix and feign to achieve fusing degradation
Note: because I introduced feign as an independent project in the form of jar package into the service, there will be many problems in the integration process, but solutions are given in the article
Open feign project
Modify UserFeign's comments as follows
@FeignClient(value = "eureka-client-order-service",configuration = FeignConfig.class,fallback = UserFeignFallBack.class)
public interface UserFeign {
@GetMapping("/user/get")
User getUser(@RequestParam("name") String name);
@PostMapping("/user/getMap")
User getUser(@RequestParam Map<String, String> param);
@PostMapping("/user/add")
User addUser(@RequestParam("name") String name, @RequestParam("email") String email);
@PostMapping("/user/addBody")
User addUser(@RequestBody User user);
}
The FeignClient annotation adds fallback = UserFeignFallBack.class. UserFeignFallBack is the implementation class of UserFeign. When the feign interface fails to call, it will automatically call the corresponding method in UserFeignFallBack and return it to the caller. The contents of UserFeignFallBack are as follows
@Component
public class UserFeignFallBack implements UserFeign {
@Override
public User getUser(String name) {
User user=new User();
user.setName(name);
user.setEmail("Interface request failed");
return user;
}
@Override
public User getUser(@RequestParam Map<String, String> param) {
User user=new User();
user.setName(param.get("name"));
user.setEmail("Interface request failed");
return user;
}
@Override
public User addUser(String name, String email) {
User user=new User();
user.setName(name);
user.setEmail("Interface request failed");
return user;
}
@Override
public User addUser(@RequestBody User user) {
return user;
}
}
The work in feign project has been completed. Now we start the fusing function of feign in consumer project
feign:
hystrix:
enabled: true
Now restart the consumer project,
Found that the project could not be started, and reported a mistake like this
No fallback instance of type class com.yangle.feign.UserFeignFallBack found for feign client eureka-client-order-service
The instance UserFeignFallBack was not found.
Now analyze the reasons for this. I can't find this instance. It indicates that feign was introduced as jar and may not have been scanned. But why didn't FeignConfig.class instance be reported as nonexistent? This is a good explanation. Remember that we added such a thing to the startup class when integrating feign,, but it seems that this only scans what he is concerned about, and does not scan the instances annotated by component, so the problem is found. Now what we need to do is to enable UserFeignFallBack to be scanned
The first solution is to scan the package path of UserFeignFallBack on the startup class. The first one is the basic package of the project
@SpringBootApplication(scanBasePackages = {"com.yangle.feign","com.yangle.eurekaclientproducter"})
The second solution: because FeignConfig can be scanned, you can manually add bean s to FeignConfig to instantiate it
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor(){
return new FeignBasicAuthRequestInterceptor();
}
class FeignBasicAuthRequestInterceptor implements RequestInterceptor{
@Override
public void apply(RequestTemplate requestTemplate) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader("token");
requestTemplate.header("token",token);
Map<String, Collection<String>> headers= requestTemplate.headers();
}
}
@Bean
public UserFeignFallBack userFeignFallBack(){
return new UserFeignFallBack();
}
}
Now restart should be OK. The project is successfully accessed http://localhost:8082/consumer/user/get Return
Indicates that the service fuse is degraded successfully.
Although the fusing degradation is completed, it doesn't seem to be perfect. Although we can respond elegantly to the user, as an administrator, we need to find out the reason for the unsuccessful call, so we must record the error information or exception. In fact, feign also provides us with another method, fallbackFactory
Modify feign comment
@FeignClient(value = "eureka-client-order-service",configuration = FeignConfig.class,fallbackFactory =UserFeignFallBackFactory.class)
public interface UserFeign {
@GetMapping("/user/get")
User getUser(@RequestParam("name") String name);
@PostMapping("/user/getMap")
User getUser(@RequestParam Map<String, String> param);
@PostMapping("/user/add")
User addUser(@RequestParam("name") String name, @RequestParam("email") String email);
@PostMapping("/user/addBody")
User addUser(@RequestBody User user);
}
@Component
public class UserFeignFallBackFactory implements FallbackFactory<UserFeign> {
@Override
public UserFeign create(Throwable throwable) {
return new UserFeign() {
@Override
public User getUser(String name) {
User user=new User();
user.setName(throwable.getMessage());
user.setEmail("Interface call failed");
return user;
}
@Override
public User getUser(Map<String, String> param) {
return null;
}
@Override
public User addUser(String name, String email) {
return null;
}
@Override
public User addUser(User user) {
return null;
}
};
}
}
All processing operations are downgraded in the create method, where you can get the exception object, record the exception information, and return the error information to the user gracefully.
summary
In this chapter, I learned about hystrix and realized the protection function of the service through hystrix. In the next section, I will lead you to learn about the API gateway zuul
You are welcome to pay attention to my public number "Le Ya code farm", reply "hystrix" to receive the source code of this section, reply "data collection", get more learning video data such as AI, big data and so on. If there is any infringement, please contact the author and delete it immediately!