文章目录
使用Hystrix实现微服务的容错处理(一)
为什么要有微服务容错处理
在实际使用过程中可能会遇到这样的情况,如果某个服务的提供者响应非常慢,那服务的消费者请求服务提供者就会产生超时的情况。如果不做处理,可能导致消费者的资源消耗,甚至拖垮整个系统。以之前的用户和电影为例,电影微服务从用户微服务获取用户信息,假如此时用户微服务网络很微弱,电影微服务在请求用户信息时就会进入一种卡死状态,此时如果消费者发起多个连接都没有响应,可能会导致电影服务的不可用,这种状态如果持续时间很长会导致整个系统的崩溃。
雪崩效应
雪崩效应的形成,如下图所示:
- 起初整个系统各个服务均可用
- 因为某种原因,Service_A可能因为网络问题等导致Service_突然不可用
- 随着时间的推移,Service_A的调用者Service_B因为服务请求Service_A的资源,导致Service_B也变得不可用,最终导致系统的崩溃
这种因“基础服务故障”导致的“级联故障”的现象称为“雪崩效应”。雪崩效应描述的是服务提供者不可用导致消费者不可用,并将不可用逐渐放大的过程。
如何容错
关于如何容错的相关知识,请参考:
使用Hystrix实现容错
Hystrix简介
Hystrix是由Netflix开源的一个延迟和容错库,用户隔离访问系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错。
- 包裹请求
使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立的线程中执行,这使用到设计模式中的“命令模式”。 - 跳闸机制
当服务的错误率达到一定的阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间 - 资源隔离
Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。 - 监控
Hystrix可以几乎实时监控运行指标和配置的变化,例如成功、失败
超时、以及被拒的请求等 - 回退机制
当请求失败、超时、被拒绝,或者当断路器打开时,执行回退逻辑。回退逻辑可由开发人员自行提供。 - 自我修复
断路器打开一段时间后,会自动进入“半开”状态。断路器打开、关闭、半开的逻辑转换。
整合Hystrix
- 添加依赖
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-hystrix', version: '1.4.7.RELEASE'
- 在启动类上加
@EnableHystrix
,为项目启动断路器的支持
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
public class MicroMovieServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MicroMovieServiceApplication.class, args);
}
}
- 修改Controller,让其中的
getUserByUserId()
方法,具备容错能力
@Controller
public class MovieController {
private static final Logger logger = LoggerFactory.getLogger(MovieController.class);
@Bean
@LoadBalanced
RestTemplate loadBalancedRestTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private UserFeignClient userFeignClient;
@ResponseBody
@HystrixCommand(fallbackMethod = "getUserFallBackByUserId")
@RequestMapping(value = "/movie/{id}", method = {RequestMethod.GET})
public BizResult getUserByUserId(@PathVariable Long id){
ServiceUser user = userFeignClient.findById(id);
BizResult bizResult = BizResult.success();
bizResult.setMessage("查询成功");
bizResult.setData(user);
return bizResult;
}
public BizResult getUserFallBackByUserId(Long id){
BizResult bizResult = new BizResult();
bizResult.setMessage(String.format("获取id为%d的用户失败",id));
bizResult.setRetCode(-1);
return bizResult;
}
}
- 启动服务
依次启动Eureka Server集群,用户微服务(这次只启动一个),电影微服务 - 在服务都正常的情况下,请求用户数据
http://127.0.0.1:8880/movie/1
- 关闭用户微服务,再次查询,结果如下:
因为用户微服务不可用,所以进入了回退方法。
Hystrix的监控
- 访问
http://127.0.0.1:8880/actuator/hystrix.stream
查看Hystrix的节点信息,第一次访问出现了404的问题,在aaplication.yml中添加以下代码,即可解决:
management:
endpoints:
web:
exposure:
include: "*"
- 再次访问
http://127.0.0.1:8880/actuator/hystrix.stream
,浏览器结果如下:
- 这是因为项目中注解@HystrixCommand没有被执行的原因,因此没有监控到任何数据
- 先访问
http://127.0.0.1:8880/movie/1
后在访问http://127.0.0.1:8880/actuator/hystrix.stream
,结果如下:
以上内容一直循环,这是因为系统会不断刷新以获得实时的监控数据。Hystrix的监控非常全面,例如HystrixCommand的名称,group的名称,断路器状态,错误率,错误数
使用Hystrix DashBoard可视化监控数据
根据上面的数据结果,发现虽然能够显示监控结果,但是数据显示不直观,所以可使用图形化的Hystrix Dashboard让监控数据图形化,可视化
- 新建一个
micro-hystrix-service-dashboard
项目 - 添加依赖
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-hystrix-dashboard', version: '2.1.2.RELEASE'
- 创建启动类并添加注解
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboarServicedApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboarServicedApplication.class, args);
}
}
- 修改服务端口,application.yml
server:
port: 8000
- 启动
micro-hystrix-service-dashboard
,访问http://127.0.0.1:8000/hystrix
,可看到Hystrix Dashboard的首页
- 在首页的页面,输入刚才在浏览器中的URL-
http://127.0.0.1:8880/actuator/hystrix.stream
,可通过图形化界面显示之前浏览器展示的信息。其各项含义如下图所示
更多内容可访问官方wiki