1. 服务雪崩
雪崩是系统中的蝴蝶效应,导致其发生的原因多种多样,有不合理的容量设计,或者是高并发下某一个方法响应变慢,亦或是某台机器的资源耗尽。从源头上我们无法完全杜绝雪崩源头的发生,但是雪崩的根本原因来源于服务之间的强依赖,所以我们可以提前评估。当整个微服务系统中,有一个节点出现异常情况,就有可能在高并发的情况下出现雪崩,导致调用它的上游系统出现响应延迟,响应延迟就会导致 Tomcat 连接本耗尽,导致该服务节点不能正常的接收到正常的情况,这就是服务雪崩行为。
2. 服务隔离
如果整个系统雪崩是由于一个接口导致的,由于这一个接口响应不及时导致问题,那么我们就有必要对这个接口进行隔离,就是只允许这个接口最多能接受多少的并发,做了这样的限制后,该接口的主机就会空余线程出来接收其他的情况,不会被那个坏了的接口占用满。Hystrix 就是一个不错的服务隔离框架。
3. Hystrix 服务隔离使用
- 导入 jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 开启 Hystrix 功能
//开启断路器功能
@EnableCircuitBreaker
- 代码
@Service
public class TicketServiceImpl implements TicketService {
@HystrixCommand
@Override
public String queryTicket() {
return "queryTicket";
}
}
4. Hystrix 服务隔离策略
- 线程池隔离。默认隔离策略
- 信号量隔离。信号量隔离是采用一个全局变量来控制并发量,一个请求过来全局变量加 1,单加到跟配置中的大小相等是就不再接受用户请求了。
参数:
execution.isolation.strategy:THREAD、SEMAPHORE。执行的隔离策略。
execution.isolation.thread.timeoutInMilliseconds:设置 HystrixCommand 执行的超时时间,单位毫秒。
execution.isolation.semaphore.maxConcurrentRequests:隔离策略为信号量的时候,该属性来配置信号量的大小,最大并发达到信号量时,后续请求被拒绝。
coreSize:执行命令线程池的最大线程数,也就是命令执行的最大并发数,默认10。
@HystrixCommand(fallbackMethod = "queryContentsFallback",
commandKey = "queryContents",
groupKey = "querygroup-one",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000000000")
},
threadPoolKey = "queryContentshystrixJackpool", threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "100")
})
@Override
public List<ConsultContent> queryContents() {
List<ConsultContent> results = restTemplate.getForObject("http://"
+ SERVIER_NAME + "/user/queryContent", List.class);
return results;
}
5. Hystrix 服务降级
服务降级是对服务调用过程的出现的异常的友好封装,当出现异常时,我们不希望直接把异常原样返回,所以当出现异常时我们需要对异常信息进行包装,抛一个友好的信息给前端。
定义降级方法,降级方法的返回值和业务方法的方法值要一样。
public List<ConsultContent> queryContentsFallback() {
// doSth
return null;
}
6. Hystrix 服务熔断
如果并发高了就可能触发hystrix的熔断。
熔断发生的三个必要条件:
- 有一个统计的时间周期,滚动窗口。相应的配置属性:metrics.rollingStats.timeInMilliseconds,默认10000毫秒
- 请求次数必须达到一定数量,相应的配置属性:circuitBreaker.requestVolumeThreshold,默认20次
- 失败率达到默认失败率,相应的配置属性:circuitBreaker.errorThresholdPercentage ,默认50%
上述3个条件缺一不可,必须全部满足才能开启 hystrix 的熔断功能。
熔断器的三个状态:
- 关闭状态。关闭状态时用户请求是可以到达服务提供方的。
- 开启状态。开启状态时用户请求是不能到达服务提供方的,直接会走降级方法
- 半开状态。当 hystrix 熔断器开启时,过一段时间后,熔断器就会由开启状态变成半开状态。半开状态的熔断器是可以接受用户请求并把请求传递给服务提供方的,这时候如果远程调用返回成功,那么熔断器就会有半开状态变成关闭状态,反之,如果调用失败,熔断器就会有半开状态变成开启状态。
circuitBreaker.sleepWindowInMilliseconds:该属性用来设置当断路器打开之后的休眠时间,休眠时间结束后断路器为半开状态,断路器能接受请求,如果请求失败又重新回到打开状态,如果请求成功又回到关闭状态
Hystrix功能建议在并发比较高的方法上使用,并不是所有方法都得使用的。
7. Hystrix 服务监控
Hystrix 进行服务熔断时会对调用结果进行统计,比如超时数、bad 请求数、降级数、异常数等等都会有统计,那么统计的数据就需要有一个界面来展示,hystrix-dashboard 就是这么一个展示 hystrix 统计结果的服务。
- 导入 jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
- 启动类
@EnableHystrixDashboard
监控界面:http://localhost:9990/hystrix
需要监控的端点(使用了hystrix组件的端点):http://localhost:8083/actuator/hystrix.stream