What is hystrix?
Hystrix is a fuse protection middleware used by netflix for microservice distributed systems. Hystrix provides an elegant response to the client after the service is unreachable 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, then the service itself may also fail. Hystrix can implement isolation between services. When a service fails, it can gracefully fall back. And downgrade to avoid chain reaction
hystrix quick start
Follow the public account "Le Zai Code Farmer" and reply to "hystrix" to get the basic projects 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 the annotation @HystrixCommand(fallbackMethod = "getUserFallback") on the userConsumerService class
getUserFallback is when the method execution times out or fails, it will call this method and give an elegant response
Add the corresponding method
//失败回调
public User getUserFallback(@RequestParam("name") String name){
User user=new User();
user.setName(name);
user.setEmail("调用失败");
return user;
}
In order to verify the effect, this time we started the two projects of eurek and consumer, so that the product service could not be adjusted directly to simulate the request timeout. This is to use hystrix alone to degrade the circuit breaker. Next, I will introduce you to the combination of hystrix and feign. Fuse downgrade
Note: Because I used feign as an independent project and introduced it into the service in the form of a jar package, there will be many problems in the integration process, but the solutions are given in the article
Open the 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);
}
Fallback = UserFeignFallBack.class is added to the FeignClient annotation. UserFeignFallBack is the implementation class of UserFeign. When the feign interface call fails, it will automatically call the corresponding method in UserFeignFallBack and return it to the caller. The content of UserFeignFallBack is as follows
@Component
public class UserFeignFallBack implements UserFeign {
@Override
public User getUser(String name) {
User user=new User();
user.setName(name);
user.setEmail("接口请求失败");
return user;
}
@Override
public User getUser(@RequestParam Map<String, String> param) {
User user=new User();
user.setName(param.get("name"));
user.setEmail("接口请求失败");
return user;
}
@Override
public User addUser(String name, String email) {
User user=new User();
user.setName(name);
user.setEmail("接口请求失败");
return user;
}
@Override
public User addUser(@RequestBody User user) {
return user;
}
}
The work in the feign project has been completed, and now we turn on the fuse function of feign in the consumer project
feign:
hystrix:
enabled: true
Now restart the consumer project,
Found that the project could not be started, and reported an error like this
No fallback instance of type class com.yangle.feign.UserFeignFallBack found for feign client eureka-client-order-service
The instance of UserFeignFallBack was not found.
Now analyze the reason for this, and I did not find this instance, which means that he was not scanned when the package was scanned. Because feign was introduced as a jar, it might not be scanned, but why did it not report that the FeignConfig.class instance does not exist? Well, this is very easy to explain. Remember when we integrated feign, we added such a thing to the startup class, ,, but this seems to only scan for his attention, and does not scan for instances annotated by component, so The problem has been found, what we need to do now is to enable UserFeignFallBack to be scanned
The first solution is to scan the package path where UserFeignFallBack is located on the startup class. The previous one is the project base package
@SpringBootApplication(scanBasePackages = {"com.yangle.feign","com.yangle.eurekaclientproducter"})
第二种解决办法,因为FeignConfig能够被扫描到,所以可以手动在FeignConfig里面添加bean,去进行实例化
@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 restarting should be fine, the project starts successfully and visit http://localhost:8082/consumer/user/get , return
It indicates that the service fuse is successfully degraded.
Although the fuse downgrade is completed, it does not seem to be perfect, because although we can respond gracefully to the user, as an administrator, we need to find out the reason for the unsuccessful call, so we must record the error message or exception. In fact, feign also provides us with another method fallbackFactory
Modify feign annotation
@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("接口调用失败");
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 error information to the user gracefully.
to sum up
In this chapter, I learned about hystrix and realized the protection function of the service through hystrix. The next section will lead you to learn about the API gateway zuul
Welcome everyone to pay attention to my public account "Le Zai Code Farmer", reply to "hystrix" to receive the source code of this section, reply to "receive information" to obtain more learning video materials such as artificial intelligence, big data, etc. If there is any infringement, please contact the author immediately delete!