在微服務架構中,根據業務來拆分紅一個個的服務,服務與服務之間能夠經過 RPC 相互調用,在 Spring Cloud 中能夠用 RestTemplate + Ribbon 和 Feign 來調用。爲了保證其高可用,單個服務一般會集羣部署。因爲網絡緣由或者自身的緣由,服務並不能保證 100% 可用,若是單個服務出現問題,調用這個服務就會出現線程阻塞,此時如有大量的請求涌入,Servlet 容器的線程資源會被消耗完畢,致使服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統形成災難性的嚴重後果,這就是服務故障的 雪崩效應。java
服務熔斷
在微服務架構中,一個請求須要調用多個服務是很是常見的,較底層的服務若是出現故障,會致使連鎖故障。當對特定的服務的調用的不可用達到一個閥值(Hystrix 默認是 5 秒 20 次) 熔斷器將會被打開,爲了不連鎖故障,會觸發服務降級。spring
服務降級
Fallback 至關因而降級操做,對於查詢操做, 咱們能夠實現一個 fallback 方法,當請求後端服務出現異常的時候,可使用 fallback 方法返回的值,fallback 方法的返回值通常是設置的默認值或者來自緩存,告知後面的請求服務不可用了,不要再請求了。後端
在 pom.xml
中添加 spring-cloud-starter-netflix-hystrix
依賴瀏覽器
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
在 Application
入口類中添加 @EnableHystrix
註解開啓 Hystrix
緩存
@SpringBootApplication @EnableDiscoveryClient @EnableHystrix public class WebAdminRibbonApplication { public static void main(String[] args) { SpringApplication.run(WebAdminRibbonApplication.class, args); } }
在業務層添加 @HystrixCommand
註解,並指定 fallbackMethod
熔斷方法。當熔斷器打開後,會觸發相應的 fallbackMethod
,也就是上面提到的服務降級網絡
@Service public class AdminService { @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiFallback") public String sayHi(String message) { return restTemplate.getForObject("http://hello-sring-cloud-service-admin/hi?message=" + message, String.class); } public String hiFallback(String message) { return "Hi,your message is :\"" + message + "\" but request error."; } }
此時關閉服務提供者,再次請求 http://localhost:8764/hi?mess... 瀏覽器會顯示 :架構
Hi,your message is :"HelloRibbon" but request error.
在 Feign 中是自帶熔斷器的,但默認是關閉的,須要在配置文件中配置打開它app
在 application.yml
中開啓熔斷器ide
feign: hystrix: enabled: true
在 Application
入口類中添加 @EnableHystrix
註解開啓 Hystrix
微服務
@SpringBootApplication @EnableDiscoveryClient @EnableHystrix public class WebAdminRibbonApplication { public static void main(String[] args) { SpringApplication.run(WebAdminRibbonApplication.class, args); } }
在業務層添加 @FeignClient
註解,並經過 fallback
屬性指定 Fallback
類。當熔斷器打開後,會觸發該 Fallback
類中的方法,也就是服務降級。
@FeignClient(value = "hello-spring-cloud-service-admin", fallback = AdminServiceFallback.class) public interface AdminService { @RequestMapping(value = "hi", method = RequestMethod.GET) public String sayHi(@RequestParam(value = "message") String message); }
在 Fallback 回調類中實現對應接口,服務調用失敗後,將錯誤提示內容返回給客戶端
@Component public class AdminServiceFallback implements AdminService { @Override public String sayHi(String message) { return "Hi,your message is :\"" + message + "\" but request error."; } }
此時再次關閉服務提供者,再次請求 http://localhost:8765/hi?mess... 瀏覽器會顯示:
Hi,your message is :"HelloRibbon" but request error.
在 Ribbon
和 Feign
項目增長 Hystrix
儀表盤監控功能,兩個項目的改造方式相同,這裏以 Feign
項目爲例。
在 pom.xml
中添加 spring-cloud-starter-netflix-hystrix-dashboard
依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
在 Application
入口類中添加 @EnableHystrixDashboard
註解
@SpringBootApplication @EnableDiscoveryClient @EnableHystrix @EnableHystrixDashboard public class WebAdminFeignApplication { public static void main(String[] args) { SpringApplication.run(WebAdminFeignApplication.class, args); } }
建立 HystrixDashboardConfiguration
配置類
@Configuration public class HystrixDashboardConfiguration { @Bean public ServletRegistrationBean getServlet() { HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; } }
啓動項目,訪問熔斷器儀表盤頁面:http://localhost:8765/hystrix.stream
超時時間(默認1000ms,單位:ms)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
:在調用方配置,被該調用方的全部方法的超時時間都是該值,優先級低於下邊的指定配置hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds
:在調用方配置,被該調用方的指定方法(HystrixCommandKey 方法名)的超時時間是該值線程池核心線程數
hystrix.threadpool.default.coreSize
:默認爲 10Queue 隊列
hystrix.threadpool.default.maxQueueSize
:最大排隊長度。默認 -1,使用 SynchronousQueue
。其餘值則使用 LinkedBlockingQueue
。若是要從 -1 換成其餘值則需重啓,即該值不能動態調整,若要動態調整,須要使用到下邊這個配置hystrix.threadpool.default.queueSizeRejectionThreshold
:排隊線程數量閾值,默認爲 5,達到時拒絕,若是配置了該選項,隊列的大小是該隊列若是 maxQueueSize
等於 -1 的話,則該選項不起做用
circuitBreaker 斷路器
hystrix.command.default.circuitBreaker.requestVolumeThreshold
:當在配置時間窗口內達到此數量的失敗後,進行短路。默認 20 個(10s 內請求失敗數量達到 20 個,斷路器開)hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds
:短路多久之後開始嘗試是否恢復,默認 5shystrix.command.default.circuitBreaker.errorThresholdPercentage
:出錯百分比閾值,當達到此閾值後,開始短路。默認 50%fallback
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests
:調用線程容許請求 HystrixCommand.GetFallback()
的最大數量,默認 10。超出時將會有異常拋出,注意:該項配置對於 THREAD 隔離模式也起做用什麼狀況下會觸發 fallback 方法
名字 | 描述 | 觸發fallback方法 |
---|---|---|
EMIT (emit) | 值傳遞 | NO |
SUCCESS (success) | 執行完成 , 沒有錯誤 | NO |
FAILURE (failure) | 執行拋出異常 | YES |
TIMEOUT (timeout) | 執行開始 , 但沒有在容許的時間內完成 | YES |
BAD_REQUEST (bad_request) | 執行拋出HystrixBadRequestException | NO |
SHORT_CIRCUITED (short_circuited) | 斷路器打開 , 不嘗試執行 | YES |
THREAD_POOL_REJECTED (thread_pool_rejected) | 線程池拒絕 , 不嘗試執行 | YES |
SEMAPHORE_REJECTED (semaphore_rejected) | 信號量拒絕 , 不嘗試執行 | YES |
什麼狀況下 fallback 方法拋出異常
名字 | 描述 | 拋異常 |
---|---|---|
FALLBACK_EMIT (fallback_emit) | Fallback值傳遞 | NO |
FALLBACK_SUCCESS (fallback_success) | Fallback執行完成 , 沒有錯誤 | NO |
FALLBACK_FAILURE (fallback_failure) | Fallback執行拋出出錯 | YES |
FALLBACK_REJECTED (fallback_rejected) | Fallback信號量拒絕 , 不嘗試執行 | YES |
FALLBACK_MISSING (fallback_missing) | 沒有Fallback實例 | YES |