Hystrix
什么是Hystrix
Hystrix是一个用于处理分布式系统延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性
Hystrix能干嘛
- 服务降级
- 服务熔断
- 服务限流
- 接近实时的监控
一、服务熔断
1.服务熔断是什么?
熔断机制是对应雪崩效应的一种微服务链路保护机制
当某个服务不可用或响应的时间太长会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息@HystrixCommand
2.代码实例(复制springcloud-provider-dept-8001模块)
1)新建一个子项目springcloud-provider-dept-hystrix-8001导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>com.giao</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-provider-dept-hystrix-8001</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency><!-- 加入eureka依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><!-- actuator完善监控信息 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 我们需要拿到实体类配置api model--><dependency><groupId>com.giao</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- junit--><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><!-- 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><!-- jetty--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency><!-- 热部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency>
</dependencies></project>
2)配置文件
server:port: 8001#mybatis配置
mybatis:type-aliases-package: com.giao.springcloud.pojoconfig-location: classpath:mybatis/mybatis-config.xmlmapper-locations: classpath:mybatis/mapper/*.xml#spring配置
spring:application:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSource #数据源driver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=UTF-8username: rootpassword: gn941030#Eureka的配置,服务注册到哪里
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/instance:instance-id: springcloud-privider-dept-hystrix-8001 #修改eureka上的默认描述信息#info配置
info:app.name: giao-springcloudcompany.name: giao
3)启动类
package com.giao.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient//在服务启动后自动注册到eureka中
@EnableDiscoveryClient//服务发现
@EnableCircuitBreaker//添加对熔断的支持
public class DeptProviderHystrix_8001 {public static void main(String[] args) {SpringApplication.run(DeptProviderHystrix_8001.class,args);}
}
4)复制springcloud-provider-dept-8001的rsources下mybatis文件夹
5)复制springcloud-provider-dept-8001的service包。dao包
6)controller
package com.giao.springcloud.controller;import com.giao.springcloud.pojo.Dept;
import com.giao.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;import java.util.List;//提供restful服务
@RestController
public class DeptController {@Autowiredprivate DeptService service;@GetMapping("/dept/get/{id}")@HystrixCommand(fallbackMethod = "hystrixGet")public Dept get(@PathVariable("id") Long id) {Dept dept = service.queryById(id);if (dept == null) {throw new RuntimeException("id" + id + "不存在");}return dept;}//备选方案public Dept hystrixGet(@PathVariable("id") Long id) {return new Dept().setDeptno(id).setDname("id" + id + "不存在,null").setDb_source("no this datebase in mysql");}
}
二、服务降级
代码实例
1.springcloud-consumer-dept-feign项目的配置文件增加feign
server:port: 80#开启降级feign.hystrix
feign:hystrix:enabled: true#Eureka配置
eureka:client:register-with-eureka: false #不像Eureka中注册自己service-url:defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
2.springcloud-api -service包新增
package com.giao.springcloud.service;import com.giao.springcloud.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;import java.util.List;
//降级
@Component
public class DeptClientServiceFailbackFactory implements FallbackFactory {public DeptClientService create(Throwable throwable) {return new DeptClientService() {public Dept queryById(Long id) {return new Dept().setDeptno(id).setDname("id->"+id+"没有对应信息,客户端提供降级信息,这个服务被关闭").setDb_source("没有数据");}public List<Dept> queryAll() {return null;}public Boolean addDept(Dept dept) {return null;}};}
}
3.DeptClientService增加注解
package com.giao.springcloud.service;import com.giao.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;import java.util.List;@Component
@FeignClient(value="SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFailbackFactory.class)
public interface DeptClientService {@GetMapping("/dept/get/{id}")public Dept queryById(@PathVariable("id") Long id);@GetMapping("/dept/list")public List<Dept> queryAll();@PostMapping("/dept/add")public Boolean addDept(Dept dept);
}
服务熔断:服务端~ 某个服务超时或异常,引起熔断 类似于保险丝
服务降级:客户端~ 从整体网站请求负载考虑 当某个服务熔断或关闭之后,服务将不再被调用 ,此时客户端,我们可以准备一个FallbackFactory,返回一个默认的值(缺省值),整体服务水平下降,但好歹能用,比直接挂掉强
三、Dashboard流监控
代码示例
1.新建springcloud-consumer-hystrix-dashboard。导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>com.giao</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-consumer-hystrix-dashboard</artifactId><dependencies>
<!-- Hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix-dashboard</artifactId><version>1.4.6.RELEASE</version></dependency><!-- Ribbon--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version></dependency><!-- eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>com.giao</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies></project>
2.编写配置文件
server:port: 9001
3.启动类
package com.giao.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;@SpringBootApplication
@EnableHystrixDashboard//开启监控
public class DeptConsumerDashboard_9001 {public static void main(String[] args) {SpringApplication.run(DeptConsumerDashboard_9001.class, args);}
}
4.监控springcloud-provider-dept-8001,在此项目中增加依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency>
5.springcloud-provider-dept-8001启动类增加一个bean,固定代码
package com.giao.springcloud;import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;@SpringBootApplication
@EnableEurekaClient//在服务启动后自动注册到eureka中
@EnableDiscoveryClient//服务发现
public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class,args);}//增加一个servlet@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet(){ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());registrationBean.addUrlMappings("/actuator/hystrix.stream");return registrationBean;}
}