@[toc]
Spring cloud uses Feign and Hystrix to realize fault-tolerant protection of services
Preface
The fault-tolerant protection of Hystrix enables the code to be spliced with the + sign when it is called. The implementation method is not elegant, as shown in the figure below.
Hystrix calls service
@HystrixCommand(fallbackMethod = "fallback1") public User getUser1(int id){ //The name of the user microservice is used to send requests to this service String servceId = "user-server"; String url = "http://" + servceId + "/getUser?id=" + id; System.out.println(url + " = " + url); User forObject = restTemplate.getForObject(url, User.class); return forObject; }
Hystrix blown
/** * Use the @ HystrixCommand annotation to specify the method to call when the method has an exception * @param id id * @return Users queried by id */ public User fallback1(int id) { return new User(id,"test user ","Query user exception!","1"); }
This is how we use Feign and Hystrix to implement service fault-tolerant protection code
/** * Fault tolerance with Feign client */ @HystrixCommand(fallbackMethod = "fallback2") public User getUser2(int id){ System.out.println(2); return userFeginInterface.getUser(id); }
Error message code
public User fallback2(int id) { return new User(id,"test user ","Query user exception!","1"); }
Code looks very elegant, no + splicing
Hystrix features
1. Circuit breaker mechanism
It is well understood by the circuit breaker that when the number of failures of the back-end service requested by the Hystrix Command exceeds a certain proportion (default 50%), the circuit breaker will switch to the open state. At this time, all requests will fail directly and will not be sent to the back-end service. After the circuit breaker remains in the open state for a period of time (default 5 seconds), Automatically switch to half-open state. At this time, the return condition of the next request will be judged. If the request is successful, the circuit breaker will switch back to closed state, otherwise it will switch to open state again. The circuit breaker of hystrix is like the insurance wire in our home circuit. Once the back-end service is unavailable, the circuit breaker will directly cut off the request chain, Avoid sending a large number of invalid requests to affect the system throughput, and the circuit breaker has the ability of self detection and recovery
2.Fallback
For query operation, we can implement a fallback method. When there is an exception in the request back-end service, we can use the value returned by the fallback method. The return value of the fallback method is generally the default value set or from the cache
3. Resource isolation
In Hystrix, resource isolation is mainly realized through thread pools. Usually, when using, we will divide multiple thread pools according to the called remote service. For example, the Command calling product service will be put into thread pool A, The main advantage of this is that the running environment is isolated. Even if there is A bug in the calling service's code or the online process pool is exhausted due to other reasons, the system will not be able to use up the running environment, It will not affect other services of the system. However, the cost is that maintaining multiple thread pools will bring additional performance overhead to the system. If there are strict performance requirements and you are sure that the client code that you call the service will not have problems, you can use the semaphores of Hystrix to isolate resources
Feign + Hystrix
Because the fuse is only used for service invocation, the server can refer to the two services in the previous article Click to arrive
Import Maven dependency first
<!-- integration hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!-- feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.7.RELEASE</version> </dependency>
Feign declares the client interface
/** * Feign It is a declarative and templated HTTP client. * Spring Cloud When the application is started, 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, * If you are using Spring Cloud Netflix to build a microservice, Feign is the best choice * */ //@Feignclient (value = "user server", fallback = helloserviceimpl. Class) or you can specify the returned class, indicating that the current customer is the interface of this return class @FeignClient(value = "user-server") public interface UserFeginInterface { //The url here must be the same as the url accessed in the service specified in the @ FeignClient annotation @RequestMapping(value = "/getUser",method = RequestMethod.GET) User getUser(@RequestParam("id") int id); }
Controller control
@RestController public class GetUserController { @Autowired private UserService userService; // Hystrix blown @RequestMapping("get1") public User getUser1(int id){ return userService.getUser1(id); } //Fegin + hystrix blown @RequestMapping("get2") public User getUser2(int id){ return userService.getUser2(id); } }
Service business layer
@Service public class UserService { @Autowired RestTemplate restTemplate; //Service discovery object @Autowired DiscoveryClient discoveryClient; @Autowired private UserFeginInterface userFeginInterface; /** * Fault tolerance with Hystrix * @param id * @return */ @HystrixCommand(fallbackMethod = "fallback1") public User getUser1(int id){ //The name of the user microservice is used to send requests to this service String servceId = "user-server"; String url = "http://" + servceId + "/getUser?id=" + id; System.out.println(url + " = " + url); User forObject = restTemplate.getForObject(url, User.class); return forObject; } /** * Fault tolerance with the Hystrix client */ @HystrixCommand(fallbackMethod = "fallback2") public User getUser2(int id){ System.out.println(2); return userFeginInterface.getUser(id); } /** * Use the @ HystrixCommand annotation to specify the method to call when the method has an exception * @param id id * @return Users queried by id */ public User fallback1(int id) { return new User(id,"test user ","Query user exception!","1"); } public User fallback2(int id) { return new User(id,"test user ","Query user exception!","1"); } }
Main method turns on Fegin fuse switch
@EnableFeignClients
Startup Test
Stop a service while testing
Normal visit Abnormal access
Code address Portal