较低级别的服务中的服务故障可能致使级联故障一直到用户。 当对特定服务的调用超过circuitBreaker.requestVolumeThreshold(默认值:20个请求)且失败百分比大于circuit.rolllingStats.timeInMilliseconds定义的滚动窗口中的circuitBreaker.errorThresholdPercentage(默认值:> 50%)时(默认值:10秒)java
设计原则:web
- 防止单个服务的故障,耗尽整个系统服务的容器(好比tomcat)的线程资源,避免分布式环境里大量级联失败。经过第三方客户端访问(一般是经过网络)依赖服务出现失败、拒绝、超时或短路时执行回退逻辑
- 用快速失败代替排队(每一个依赖服务维护一个小的线程池或信号量,当线程池满或信号量满,会当即拒绝服务而不会排队等待)和优雅的服务降级;当依赖服务失效后又恢复正常,快速恢复
- 提供接近实时的监控和警报,从而可以快速发现故障和修复。监控信息包括请求成功,失败(客户端抛出的异常),超时和线程拒绝。若是访问依赖服务的错误百分比超过阈值,断路器会跳闸,此时服务会在一段时间内中止对特定服务的全部请求
- 将全部请求外部系统(或请求依赖服务)封装到HystrixCommand或HystrixObservableCommand对象中,而后这些请求在一个独立的线程中执行。使用隔离技术来限制任何一个依赖的失败对系统的影响。每一个依赖服务维护一个小的线程池(或信号量),当线程池满或信号量满,会当即拒绝服务而不会排队等待
功能特性:spring
- 请求熔断: 当Hystrix Command请求后端服务失败数量超过必定比例(默认50%), 断路器会切换到开路状态(Open). 这时全部请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN)。这时会判断下一次请求的返回状况, 若是请求成功, 断路器切回闭路状态(CLOSED), 不然从新切换到开路状态(OPEN). Hystrix的断路器就像咱们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 而且断路器有自我检测并恢复的能力.
- 服务降级:Fallback至关因而降级操做. 对于查询操做, 能够实现一个fallback方法, 当请求后端服务出现异常的时候, 可使用fallback方法返回的值. fallback方法的返回值通常是设置的默认值或者来自缓存
- 依赖隔离(采用舱壁模式,Docker就是舱壁模式的一种):在Hystrix中, 主要经过线程池来实现资源隔离. 一般在使用的时候咱们会根据调用的远程服务划分出多个线程池
- 请求缓存
- 请求合并
Ribbon集成断路器
一、基于以前的服务,引入Hystrix依赖json
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
二、开启断路器功能后端
@EnableCircuitBreaker:加载断路器配置api
@EnableCircuitBreaker
也可使用@SpringCloudApplication注解:三合一缓存
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
三、建立fallback方法,指定为某个接口的降级tomcat
@SpringCloudApplication public class ConsumerRibbonApplication { public static void main(String[] args) { SpringApplication.run(ConsumerRibbonApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } @RestController @RequestMapping("/api/v1/consumer") class ProviderController { private static final String SERVICE_NAME = "provider-server"; private static final String GET_PORT = "/api/v1/provider/port"; @Resource private RestTemplate restTemplate; @GetMapping @HystrixCommand(fallbackMethod = "consumerFallback") public String consumer() { ResponseEntity<String> forEntity = restTemplate.getForEntity("http://" + SERVICE_NAME + GET_PORT, String.class, (Object) null); return forEntity.getBody(); } public String consumerFallback() { return "provider error"; } } }
hystrix:配置网络
hystrix: command: default: execution: isolation: strategy: SEMAPHORE thread: timeoutInMilliseconds: 60000 shareSecurityContext: true
验证:app
访问消费者:http://localhost:3000/api/v1/consumer
得到响应:2000
Feign集成断路器
引入依赖和开启配置和Ribbon同样
一、在@FeignClient上声明
@FeignClient(name = "provider-server", fallback = ProviderClientFallback.class) @RequestMapping("/api/v1/provider") public interface ProviderClient { @GetMapping("/port") String port(); }
二、开启配置feign.hystrix.enabled=true
server: port: 3001 spring: application: name: consumer-server-feign profiles: active: dev cloud: config: label: master profile: ${spring.profiles.active} discovery: service-id: config-server enabled: true feign: hystrix: enabled: true eureka: client: service-url: defaultZone: http://127.0.0.1:8761/eureka/
三、编写fallback类
public class ProviderClientFallback implements ProviderClient { @Override public String port() { return "provider error"; } }
四、在声明类@FeignClient上指定fallback属性
@FeignClient(name = "provider-server", fallback = ProviderClientFallback.class) @RequestMapping("/api/v1/provider") public interface ProviderClient { @GetMapping("/port") String port(); }
验证:
访问消费者:http://localhost:3000/api/v1/consumer
得到响应:2000
关闭生产者服务:http://localhost:3000/api/v1/consumer
得到响应:provider error
五、换成指定FallbackFactory,能够获取到异常对象
@FeignClient(name = "provider-server", fallbackFactory = HystrixClient.HystrixClientFallback.class, path = "/api/v1/provider") public interface HystrixClient { @GetMapping("/port") String port(); @Component class HystrixClientFallback implements FallbackFactory<HystrixClient> { @Override public HystrixClient create(Throwable throwable) { return new HystrixClient() { @Override public String port() { return "provider error: " + throwable; } }; } } }
验证:
访问消费者:http://localhost:3000/api/v1/consumer
得到响应:2000
关闭生产者服务:http://localhost:3000/api/v1/consumer
得到响应:provider error: java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: provider-server
Hystrix Metrics Stream
包含依赖关系spring-boot-starter-actuator
,设置 management.endpoints.web.exposure.include: hystrix.stream
。这样作会将/actuator/hystrix.stream
管理端点公开
依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
配置:
# 所有开放监控端点 management: endpoints: web: exposure: include: "*"
验证:
GET /actuator/metrics GET /actuator/metrics/{requiredMetricName}
{[/actuator/metrics/{requiredMetricName}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" {[/actuator/metrics],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
断路器:Hystrix仪表板
一、添加依赖项:spring-cloud-starter-netflix-hystrix-dashboard
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
二、使用@EnableHystrixDashboard注解开启仪表盘
@EnableFeignClients @SpringCloudApplication @EnableHystrixDashboard public class ConsumerFeignApplication { }
三、访问/hystrix
并将仪表板指向/hystrix.stream
Hystrix客户端应用程序中的单个实例的端点。