Hystrix是什么
概念来自鲁班学院 - 商鞅
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异 常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至 雪崩。
Hystrix的使用
- pom引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 启动类加入注解
@EnableHystrix
或者@EnableCircuitBreaker
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients
public class EurekaConsumerApp {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaConsumerApp.class)
.web(WebApplicationType.SERVLET).run(args);
}
}
服务降级、超时
降级:某个微服务响应时间过长,或者不可用了,不能把错误信息返回出来,或者让他一直卡在那里,所以要在准备一个对应的策略,当出现这种情况时,直接调用这个策略,快速返回请求。
- 方法上添加
@HystrixCommand
注解,并指定fallbackMethod降级策略 - 提供服务方模拟异常
@RestController
@RequestMapping("client")
public class IndexController {
@Autowired
RestTemplate restTemplate;
@GetMapping
@HystrixCommand(fallbackMethod = "selectFallback")
public String select(String type){
HashMap<String, String> map = new HashMap<>();
map.put("type",type);
return restTemplate.getForObject("http://EUREKA-PRODUCT/product?type={type}", String.class,map);
}
public String selectFallback(String type) {
return "服务降级:" + type;
}
}
@RestController
@RequestMapping("product")
public class UserController {
private static String shareName = "init name";
@Value("${server.port}")
private String serverPort;
@GetMapping
public String select(String type) throws InterruptedException {
if ("异常".equals(type)){
throw new RuntimeException("模拟异常");
}
if ("超时".equals(type)){
System.out.println("超时测试");
Thread.sleep(3000);
}
return serverPort + ":" + shareName;
}
}
超时:Hystrix有默认超时监听机制,当请求超过1s中就会超时,超时同样会触发降级。这里可以通过配置类来进行配置超时时长。
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000 # 超时进行降级
使用场景:双十一秒杀这种 或者促销活动,系统承载不了这么大的并发时,可以考虑先关闭一些不重要的微服务(在降级方法里面返回一个比较友好的信 息),把资源让给主微服务。
熔断、限流
熔断:熔断就像保险丝一样,当你的电路出现故障时,hystrix就会采取熔断机制,禁止你调用服务。断开后, 仍会偶尔调用一次,用来判断服务是否恢复
hystrix:
command:
default:
circuitBreaker:
requestVolumeThreshold: 10 # default 20 此属性设置滚动窗口中将触发电路的请求的最小数量
metrics:
rollingStats:
timeInMilliseconds: 10000 # 和requestVolumeThreshold配合使用, 10s内10次错误将打开断路器
限流:限制微服务的使用量。比如限制线程数。
@GetMapping
@HystrixCommand(fallbackMethod = "selectFallback" ,
threadPoolKey = "order",
threadPoolProperties ={@HystrixProperty(name = "coreSize",value = "2")
,@HystrixProperty(name = "maxQueueSize",value = "1")})
public String select(String type){
HashMap<String, String> map = new HashMap<>();
map.put("type",type);
return restTemplate.getForObject("http://EUREKA-PRODUCT/product?type={type}",String.class,map);
}
threadPoolKey 就是在线程池唯一标识, hystrix 会拿你这个标识去计数,看线程占用是否超过了, 超过了就会直 接降级该次调用
比如, 这里coreSize给他值为2 那么假设你这个方法调用时间是3s执行完, 那么在3s内如果有超过2个请求进来的 话, 剩下的请求则全部降级
熔断和降级的区别?
Feign整合Hystrix
-
application.yml配置,打开
feign: hystrix: enabled: true
-
Feign接口修改
@FeignClient(name = "EUREKA-PRODUCT",fallbackFactory = UserClientFallBack.class,path = "/product") public interface UserClient { @GetMapping public String select(@RequestParam("type") String type); }
@Component public class UserClientFallBack implements UserClient{ @Override public String select(String type) { return "服务降级:Feign hystrix"; } }
-
如果拿到具体的错误信息,则如下修改
@Component public class UserClientFallBackFactory implements FallbackFactory<UserClient> { @Override public UserClient create(Throwable throwable) { return new UserClient() { @Override public String select(String type) { String message = throwable.getMessage(); System.err.println(message); return "服务降级:Feign hystrix"+message; } }; } } @FeignClient(name = "EUREKA-PRODUCT",fallbackFactory = UserClientFallBackFactory.class,path = "/product") public interface UserClient { @GetMapping public String select(@RequestParam("type") String type); }