分布式系统面临的问题
复杂分布式系统中服务通常存在数十个依赖关系,每个依赖在某些时候不可避免的存在失败的情况。
服务雪崩
多个微服务之间调用的时候,假设服务A调用服务B和服务C,而服务B和服务C又调用其他服务,这就是“扇出”,如果“扇出”的链路上某个服务的响应时间过长或者不可用,对服务A就会造成越来越多的系统资源占用,进而引起系统崩溃,即“雪崩效应”。
Hystrix简介
一个用于处理分布式系统的延迟和容错的开源库,上面说到在分布式系统中不可避免地的存在失败的情况,hystrix可以保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障时,通过断路器的故障监控(类似与熔断丝),向调用方返回一个预期的可处理的备选响应,而不是长时间的等待或抛出无法处理的异常,这样就可以保证调用方不会长时间的、不必要的占用,从而避免故障在分布式系统中的蔓延乃至雪崩。
Hystrix能干吗?
- 服务熔断
- 服务降级
- 服务限流
- 接近实时的监控
- … …
Hystrix的工作原理:
- 防止任何单个依赖项耗尽所有容器(例如Tomcat)用户线程
- 减少负载并快速失败,而不是排队
- 在可行的情况下提供备用,以保护用户免受故障的影响
- 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一种依赖关系的影响
- 通过近实时指标,监视和警报优化发现时间
- 通过在Hystrix的大多数方面中以低延迟传播配置更改来优化恢复时间,并支持动态属性更改,这使您可以通过低延迟反馈回路进行实时操作修改。
- 防止整个依赖客户端执行失败,而不仅仅是网络通信失败
服务熔断是什么?
对微服务雪崩效应的一种链路保护机制,当扇出链路中微服务响应时间过长或不可用时,会进行服务的降级,进而熔断该服务节点的调用,快速返回错误的响应信息,当检测到该链路访问正常时恢复该链路的正常调用。spring cloud中hystrix会监控微服务的调用,当失败调用达到一定的阈值,默认为5秒20次失败调用就会启动熔断机制,熔断机制的注解为@HystrixCommand
唯一的注解
原理简单介绍完毕,接下来开始动手实现
1)引入依赖
<!-- Hystrix依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
2)@HystrixCommand
熔断器配置
@GetMapping("/query/{id}")
@HystrixCommand(fallbackMethod = "queryHystrixUserById") //指定异常熔断方法
public String queryUserById(@Param(value = "id")Long id){
return new User().setUsername("没有查到用户信息")
.setPass("123")
.toString();
}
public String queryHystrixUserById(@Param(value = "id")Long id){
User user = userService.queryUserById(id);
return user.toString();
}
3)主启动类开启熔断机制
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker //开启hystrix熔断器
public class ProHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(ProHystrixApplication.class,args);
}
}
服务熔断处理完成
服务熔断处理完成
服务熔断处理完成
服务降级思想
降级指的是当服务的提供方不可使用的时候,程序不会出现异常,而会出现本地的操作调用。
例如:年底 12306 都是最繁忙的时候,那么在这个情况会发现有一些神奇的情况:当到了指定的时间大家开始抢票的 时候,如果你不抢,而后查询一些冷门的车次,票有可能查询不出来,因为这个时候会将所有的系统资源给抢票调度了,而其它的 服务由于其暂时不受到过多的关注,这个时候可以考虑将服务降级(服务暂停)
服务的降级处理是在客户端实现的,与你的服务器端没有关系
服务降级的实现
1)服务降级类
public class IUserServiceFallFatory implements FallbackFactory { //实现FallbackFactory.create方法
public IUserService create(Throwable throwable) {
return new IUserService() {
public boolean addUser(User user) {
return false;
}
public User queryUserById(Long id) {
return new User().setUsername("未查询到用户");
}
public List<User> queryUserList() {
return null; //不建议直接返回空,不利于前端解析
}
};
}
}
2)关联客户端接口
//value:微服务名称 fallbackFactory:服务降级
@FeignClient(value = "pro_user",fallbackFactory = IUserServiceFallFatory.class) //配置服务降级
public interface IUserService {
@GetMapping("/api/user/add")
public boolean addUser(User user);
@GetMapping("/api/user/query/{id}")
public User queryUserById(@PathVariable("id")Long id);
@GetMapping("/api/user/query")
public List<User> queryUserList();
}
3)配置开启feign—>hystrix的服务降级
feign:
hystrix:
enabled: true #开启服务降级
服务降级处理完成
服务降级处理完成
服务降级处理完成