文章目录
- 一、Hystrix应用场景
- 二、Hystrix简单使用
- 1.服务降级---生产者
- 2.服务降级---消费者
- 1.控制类中针对每个特定的方法做服务降级
- 2.控制类中做统一的服务降级
- 3.在Feign接口服务层做服务降级
- 3.服务熔断---生产者
- 1.服务熔断概述
- 2.服务熔断的三种状态
- 3.服务熔断的详细代码与效果
- 4.断路器的三个重要参数
- 3.服务监控---Hystrix Dashboard
- Hystrix Dashboard 报错:Unable to connect to Command Metric Stream.
在微服务中,服务与服务之间通过远程方法调用,很有可能出现网络异常、服务自身错误等导致服务不可用,甚至由于服务之间的互相依赖,导致服务级联故障,形成服务雪崩。为了解决这个问题,引入了Spring Cloud Hystrix.
一、Hystrix应用场景
1. 服务降级(Fallback):
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作
出现场景:
- 程序运行异常
- 超时
- 服务熔断触发服务降级
- 线程池/信号量打满触发服务降级
2. 服务熔断(Break):
服务熔断一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。服务熔断是建立在服务降级的基础上的,类似于SpringCloud建立在SpringBoot的基础上。
3. 服务限流(Flow Limit):
服务限流主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。
二、Hystrix简单使用
1.服务降级—生产者
- 导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 在提供服务的service方法上加上
@HystrixCommand(fallbackMethod = "处理降级的方法")
注解
@Service
public class HystrixService {
/**
* 服务降级
*/
@HystrixCommand(fallbackMethod = "requestErrorHandler")
public String requestError() {
int a = 10 / 0; //这里将抛出异常,触发服务降级
return "request Error" + a;
}
/**
*触发服务降级后执行此方法
*/
public String requestErrorHandler() {
return "CLOUD-PAYMENT-HYSTRIX-SERVICE:8004:request Error fallback";
}
}
- 主启动类上添加
@EnableCircuitBreaker
注解
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class OrderHystrixMain8084 {
public static void main(String[] args) {
SpringApplication.run(OrderHystrixMain8084.class, args);
}
}
可以看到我们访问直接访问这个服务,触发了服务降级,调用了服务降级对应的处理方法。
2.服务降级—消费者
在生产者和消费者端都可以做服务降级,但是在消费者端做服务降级更加灵活,对于生产者端挂掉了也能做出相应处理,所以一般推荐在消费者端做服务降级.
下面的操作也需要导入依赖和在启动类上加上@EnableCircuitBreaker
注解,就不都提了
1.控制类中针对每个特定的方法做服务降级
步骤:添加@HystrixCommand()
注解并指明服务降级对应的处理方法
@RestController
@RequestMapping("/consumer/hystrix")
public class FeignOrderController {
@Resource
private OpenFeignOrderService feignOrderService;
//为getError方法做服务降级,对应服务降级方法为requestErrorHandler
@HystrixCommand(fallbackMethod = "requestErrorHandlreer")
@GetMapping("/error")
public CommonResult getError() {
int a = 10 / 0; //这里将抛出异常,触发服务降级
return feignOrderService.getError();
}
//服务降级处理
public CommonResult requestErrorHandler() {
return new CommonResult(500, "CLOUD-ORDER-FEIGN-HYSTRIX-SERVICE:80:request Error fallback", null);
}
}
2.控制类中做统一的服务降级
但我们有很多方法时,每个都要指明对应的服务降级处理方法(代码膨胀),是很麻烦的事。比如访问哪个方法都可能出现访问超时的异常,可以都由同一个服务降级方法进行处理。所以统一的服务降级处理是很有必要的。
步骤:在控制类上添加@DefaultProperties(defaultFallback = "统一的服务降级处理方法")
,在需要服务降级的方法上加上@HystrixCommand
注解
@RestController
@RequestMapping("/consumer/hystrix")
//统一的服务降级处理
@DefaultProperties(defaultFallback = "requestGlobeErrorHandler")
public class FeignOrderController {
@Resource
private OpenFeignOrderService feignOrderService;
@HystrixCommand
@GetMapping("/globe/error")
public CommonResult getGlobeError() {
int a = 10 / 0;
return feignOrderService.getError();
}
public CommonResult requestGlobeErrorHandler() {
return new CommonResult(500, "CLOUD-ORDER-FEIGN-HYSTRIX-SERVICE:80:request Globe Error fallback", null);
}
}
3.在Feign接口服务层做服务降级
之前的两种服务降级的方法,写在控制类中,与业务逻辑混在一起(代码混乱),耦合度高。但是通过Feign接口层进行调用时又不能实例化。解决方法就是新建一个服务降级类并实现FeignService层的方法.
步骤:Feign接口层指定fallback类,fallback类实现Feign接口方法,编写服务降级后处理逻辑。
OpenFeignOrderService.java
@Service
@FeignClient(value = "CLOUD-PAYMENT-HYSTRIX-SERVICE", fallback = OpenFeignOrderServiceFallback.class)
public interface OpenFeignOrderService {
@GetMapping("/hystrix/ok")
CommonResult getOk();
@GetMapping("/hystrix/error")
CommonResult getError();
}
OpenFeignOrderServiceFallback.java
@Component
public class OpenFeignOrderServiceFallback implements OpenFeignOrderService {
@Override
public CommonResult getOk() {
return new CommonResult(500, "CLOUD-ORDER-FEIGN-HYSTRIX-SERVICE:80:request Error fallback by fallback class", null);
}
@Override
public CommonResult getError() {
return new CommonResult(500, "CLOUD-ORDER-FEIGN-HYSTRIX-SERVICE:80:request Error fallback by fallback class", null);
}
}
3.服务熔断—生产者
1.服务熔断概述
2.服务熔断的三种状态
3.服务熔断的详细代码与效果
@Service
public class HystrixService {
/**
* 服务熔断:在10秒窗口期中10次请求有6次是请求失败的,断路器将起作用
*/
@HystrixCommand(fallbackMethod = "requestBreakHandler", commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "1000"), //时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),//失败率达到多少后跳闸
})
public String requestBreak(int id) {
int a = 10 / id;
return "test break: " + a;
}
/***
*触发服务熔断后执行此方法
*/
public String requestBreakHandler(int id) {
return "CLOUD-PAYMENT-HYSTRIX-SERVICE:8004:request Error Break:" + id;
}
}
咋一看,服务熔断和服务降级的代码差不多,无非多了几个@HystrixProperty
属性(可在HystrixCommandProperties.java
中查看所有属性),但是如果你触发服务熔断(在10秒窗口期中10次请求有6次是请求失败的),断路器起作用,进入熔断打开状态后,即使你访问的是正常的请求,也会进入熔断处理方法,过一会才会自动恢复.
4.断路器的三个重要参数
3.服务监控—Hystrix Dashboard
Hystrix Dashboard 启动的端口:9001
被监控服务启动端口:8084
- 导入依赖:
Hystrix Dashboard(9001)导入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
被监控服务(8084)导入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- Hystrix Dashboard(9001)启动类上增加
@EnableHystrixDashboard
注解
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashBoard9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashBoard9001.class, args);
}
}
- 访问
http://localhost:9001/hystrix
可以看到如下画面 - 输入框中输入需要监控的服务实例地址
http://localhost:8084/actuator/hystrix.stream
,点击Monitor Stream
按钮.
Hystrix Dashboard 报错:Unable to connect to Command Metric Stream.
恭喜你,肯定会报错😄:Unable to connect to Command Metric Stream.
原因:被监控的服务实例(8084)的EndPoint /actuator/hystrix.stream
没有暴露出来,你可以通过访问 http://localhost:8084/actuator/hystrix.stream
来验证,一定是404.
解决方法:
- 方法一(推荐):修改被监控的服务实例(8084)的yml文件
management:
endpoints:
web:
exposure:
include: hystrix.stream
- 方法二:被监控的服务实例(8084)的启动类中增加一个Servlet,修改映射
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class OrderHystrixMain8084 {
public static void main(String[] args) {
SpringApplication.run(OrderHystrixMain8084.class, args);
}
/**
* 此配置是为了服务监控而配置,与服务器容错本身无关,springcloud升级后的坑
* ServletRegistrationBean因为springboot的默认路径不是/hystrix.stream
* 只要在自己的项目里配置上下文的servlet就可以了
*/
@Bean
public ServletRegistrationBean getservlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean<HystrixMetricsStreamServlet> registrationBean = new ServletRegistrationBean<>(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}