較低級別的服務中的服務故障可能致使級聯故障一直到用戶。 當對特定服務的調用超過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客戶端應用程序中的單個實例的端點。