简述
什么是 Hystrix?
- 在分布式环境中,不可避免地会遇到所依赖的服务挂掉的情况,Hystrix 可以通过增加 延迟容忍度 与 错误容忍度,来控制这些分布式系统的交互。Hystrix 在服务与服务之间建立了一个中间层,防止服务之间出现故障,并提供了失败时的 fallback 策略,来增加你系统的整体可靠性和弹性。
- 中文文档
服务熔断
样例
提供在故障时的应急方法(fallback)
-
熔断是在服务提供者上进行的。
-
选其中一个服务提供者使用Hystrix
-
步骤如下
- 导入依赖
- 启动类上使用
@EnableCircuitBreaker
//开启熔断 - controller层创建应急方法(fallback),使用
@HystrixCommand
- 代码 依赖
<dependencies>
<!-- 实体类-->
<dependency>
<groupId>org.example</groupId>
<artifactId>SpringCloud-Api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
- controller
//提供restful 服务
@RestController
public class DeptController {
@Autowired
private DeptService service;
//用8001端口不行,非要用得post请求。消费服务端ok
@RequestMapping(value = "/add")
public boolean add(@RequestBody Dept dept) {
System.out.println(dept.getDname());
return service.addDept(dept);
}
@GetMapping("/byId/{id}")
@HystrixCommand(fallbackMethod = "HystrixgetDeptById")//抛出异常时使用备选方法
public Dept getDeptById(@PathVariable(value = "id") int id) {
Dept dept = service.getById(id);
if (dept == null) {
throw new RuntimeException("id=>" + id + "查无此人");
}
return dept;
}
@GetMapping("/getAll")
public List<Dept> getAll() {
return service.getAll();
}
//备选方法
public Dept HystrixgetDeptById(int id) {
return new Dept()
.setDeptId(id)
.setDname("id=>" + id + "没有对应的信息,nul1--@Hystrix")
.setDb_source("数据库中没有对应数据");
}
}
- 启动类
@EnableEurekaClient
/*
客户端的便利注释,用于启用Eureka发现配置(特别是)。
如果您想发现并确定知道它是您想要的Eureka,请使用此(可选)。
它所做的只是打开发现功能,并让自动配置找到可用的eureka类(即,您在类路径上也需要Eureka)。
*/
@SpringBootApplication
@EnableCircuitBreaker//开启熔断
public class DeptProvider_Hystrix_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_Hystrix_8001.class,args);
}
}
小结
服务降级
- 在整体资源不够的时候,适当放弃部分服务,将主要的资源投放到核心服务中。
样例
步骤
- 导入依赖
- 在api项目实现接口FallbackFactory,创建后备实例
- 在api的service上的注解
@FeignClient
添加参数fallbackFactory = xxx.class
(FallbackFactory的实现类) - 在服务消费者配置application.yaml
feign.hystrix.enabled: true
- 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在api项目实现接口FallbackFactory
/*
返回适合给定原因的后备实例
原因–通常与com.netflix.hystrix.AbstractCommand.getExecutionException()对应
*/
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<FeignDeptService> {
@Override
public FeignDeptService create(Throwable cause) {
return new FeignDeptService(){//实现接口
@Override
public boolean addDept(Dept dept) {
return false;
}
@Override
public Dept getById(int id) {
return new Dept()
.setDeptId(id).setDname("id=>"+id+"无法查询")
.setDb_source("服务器已关闭,稍后开启");
}
@Override
public List<Dept> getAll() {
List<Dept> list= new ArrayList<>();
list.add(new Dept().setDname("服务器已关闭,稍后开启"));
return list;
}
};
}
}
api中的service
@Service
@FeignClient(value= "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class)//value=服务id
public interface FeignDeptService {
@RequestMapping(value = "/add")
boolean addDept(@RequestBody Dept dept);
@GetMapping("/byId/{id}")
Dept getById(@PathVariable(value = "id") int id);
@GetMapping("/getAll")
List<Dept> getAll();
}
- 服务消费者启动类
@SpringBootApplication//(scanBasePackages = "com.cloud.service")
@EnableEurekaClient
@EnableFeignClients//(basePackages = {"com.cloud.service"})
//@ComponentScan(basePackages = "com.cloud.service")//需要加,不然找不到工厂类
public class FeignDeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(FeignDeptConsumer_80.class,args);
}
}
小结
服务熔断:在服务端进行。
服务降级:当服务端不可用时,服务消费端自给自足。
熔断监控(Breaker Dashboard)
-
只能监控有熔断方法的服务
步骤
- 创建Hystrix Dashboard项目
- 导入依赖,服务提供者和Dashboard要导依赖
- 配置文件
- 在需要监控的服务端创建HystrixMetricsServlet
创建Hystrix Dashboard项目创建Hystrix Dashboard项目
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
服务提供者要导
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Hystrix Dashboard项目 启动类
@SpringBootApplication
@EnableHystrixDashboard
public class DeptConsumerDashboard_9001 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumerDashboard_9001.class,args);
}
}
配置文件application.yaml
server:
port: 9001
hystrix:
dashboard:
proxy-stream-allow-list: 'localhost'
启动9001,访问http://localhost:9001/hystrix
监控的服务端创建HystrixMetricsServlet
@EnableEurekaClient
/*
客户端的便利注释,用于启用Eureka发现配置(特别是)。
如果您想发现并确定知道它是您想要的Eureka,请使用此(可选)。
它所做的只是打开发现功能,并让自动配置找到可用的eureka类(即,您在类路径上也需要Eureka)。
*/
@SpringBootApplication
@EnableCircuitBreaker//开启熔断
public class DeptProvider_Hystrix_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_Hystrix_8001.class,args);
}
//增加HystrixMetricsServlet
@Bean
public ServletRegistrationBean hystrixMetricsServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
}
如何使用
- 先访问有
@HystrixCommand
注解的方法,
- 然后访问http://localhost:8001/actuator/hystrix.stream , 端口号是访问有
@HystrixCommand
方法的。
本例是8001端口有熔断方法
- 在Dashboard页面输入http://localhost:8001/actuator/hystrix.stream。
- 最后出现