Hystrix服务熔断
Hystrix的服务熔断是一种保护机制,用于防止故障和延迟的影响扩散到整个系统。当底层依赖的服务发生连续故障或错误率过高时,Hystrix将会触发服务熔断,暂时停止向该服务发送请求,并快速失败返回一个备选响应。这样可以避免对不可靠的服务进行无谓的重试,保护系统的稳定性。
一、引入依赖
1 <dependency> 2 <groupId>org.springframework.cloud</groupId> 3 <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> 4 </dependency>
二、启用熔断功能
与服务降级类似,在启动类上添加@EnableCircuitBreaker注解来启用Hystrix的断路器功能。
1 import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 import org.springframework.boot.web.servlet.ServletRegistrationBean; 5 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 import org.springframework.cloud.netflix.hystrix.EnableHystrix; 7 import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 8 import org.springframework.cloud.openfeign.EnableFeignClients; 9 import org.springframework.context.annotation.Bean; 10 11 /** 12 * @Classname HystrixApplication 13 * @Created by Michael 14 * @Date 2023/7/17 15 * @Description 服务降级 16 */ 17 @SpringBootApplication 18 @EnableFeignClients 19 //@EnableHystrix 20 @EnableCircuitBreaker 21 @EnableHystrixDashboard 22 public class HystrixApplication { 23 /** 24 * 启用hystrix的/actuator/hystrix.stream地址映射 25 * @return 26 */ 27 @Bean 28 public ServletRegistrationBean getServlet(){ 29 HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); 30 ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); 31 registrationBean.setLoadOnStartup(1); 32 registrationBean.addUrlMappings("/actuator/hystrix.stream"); 33 registrationBean.setName("HystrixMetricsStreamServlet"); 34 35 return registrationBean; 36 } 37 38 public static void main(String[] args) { 39 SpringApplication.run(HystrixApplication.class,args); 40 } 41 }
三、定义熔断降级逻辑
在需要进行熔断的方法上,通过@HystrixCommand注解定义熔断降级逻辑,并指定备用方法。
1 /** 2 * 熔断处理 3 * @param userId 4 * @param number 5 * @return 6 */ 7 @GetMapping("hystrix/break/{id}") 8 @HystrixCommand(fallbackMethod = "getUserBreaker", commandProperties = { 9 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), 10 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), 11 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500") 12 }) 13 public HttpResponseResult getUser2(@PathVariable("id")Integer userId, @RequestParam int number) { 14 System.out.println("userId => "+userId); 15 if(number % 3 == 2){ 16 System.out.println(number + " is bad parameter"); 17 18 throw new IllegalArgumentException(number+" is bad parameter"); 19 } 20 21 if(number % 3 == 0){ 22 try { 23 System.out.println(number + " is bad parameter"); 24 Thread.sleep(600); 25 } catch (InterruptedException e) { 26 System.out.println(e.toString()); 27 } 28 } 29 30 HttpResponseResult result = new HttpResponseResult<UserVo>(); 31 UserVo userVo= userClient.getUser(userId); 32 result.setStatusCode(HttpStatus.OK.value()); 33 result.setMessage(HttpStatus.OK.getReasonPhrase()); 34 System.out.println(userVo); 35 result.setData(userVo); 36 return result; 37 } 38 39 public HttpResponseResult getUserBreaker(Integer userId, @RequestParam int number) { 40 System.out.println("降级处理"); 41 HttpResponseResult result = new HttpResponseResult<UserVo>(); 42 result.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); 43 result.setMessage(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); 44 result.setData(new UserVo()); 45 return result; 46 }
在上述示例中,通过@HystrixProperty
注解可以覆盖全局配置,对特定方法进行独立的熔断参数设置。通过number参数控制模拟场景,number为
3n+1 返回正常请求,number为3n+2模拟请求失败,number为3n模拟请求超时(n=0,1,2,...)。
当该方法发生连续故障或错误率达到阈值时,Hystrix将会触发熔断,不再向该服务发送请求,而是立即调用备用方法fallbackMethod
返回备选响应。
通过使用Hystrix的服务熔断功能,可以及时隔离不可靠的服务,并快速失败,避免对故障服务的无谓重试。这有助于保护系统的可用性和稳定性,提升用户体验。
四、测试
准备provider,提供查询数据库api,hystrix module通过feign框架请求provider的api获得数据。
4.1 正常请求
4.2 请求失败
4.3 请求超时
设置了等待时间为500ms,请求超时了,所以看到的是降级后的处理,要注意的时,这里虽然是降级处理了,但是实际上还是请求了provider的api并且成功返回数据,只是超时了,hystrix返回了降级后的结果。