雪崩問題:
用戶的一個請求,需要若干個服務完成才能響應,若一個服務未發生相應,則會卡在這,導致請求未響應,同時也會佔用服務器的連接數。
Hustrix解決雪崩問題的方法:
1)線程隔離
不同的服務請求,用不同的線程池隔離。儘管線程池佔滿們也只是部分資源。
2)服務熔斷。降級。
當線程池拍滿以後,線程池設置時間,超時之後,服務降級,返回錯誤信息。保護優先服務。
使用:
1)導入依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> hystrix: # command: # default: # execution: # isolation: # thread: # timeoutInMilliseconds: 3000 #全局延遲時間,超過後熔斷降級 # user-service: #針對某個服務或方法 # execution: # isolation: # thread: # timeoutInMilliseconds: 3000
2)家註解在啓動類上
//@EnableCircuitBreaker //熔斷 //@EnableDiscoveryClient//服務客戶端 //@SpringBootApplication @SpringCloudApplication public class ConsumerApplication { @Bean @LoadBalanced //底層用了攔截器,攔截restTemplate 的http請求,使用負載均衡算法處理請求 public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class); } }
3)編寫降級邏輯
@RestController @RequestMapping("consumer/pojo") @DefaultProperties(defaultFallback = "defaultFallback") //默認fallback public class ConsumerController { @Autowired private RestTemplate restTemplate; //@Autowired //private RibbonLoadBalancerClient client; @GetMapping("{id}") @HystrixCommand(commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")//自定義超時時間。 })// 開啓降級處理在該方法上 public String queryById(@PathVariable("id")Integer id){ String url="http://user-service/user/"+id; String user=restTemplate.getForObject(url,String.class); return user; } public String queryByIdFall(Integer id){ return "繁忙"; } public String defaultFallback(){ return "繁忙!!!"; } }
三種狀態的轉換:
closed->open:正常情況下熔斷器爲closed狀態,當訪問同一個接口次數超過設定閾值並且錯誤比例超過設置錯誤閾值時候,就會打開熔斷機制,這時候熔斷器狀態從closed->open。
open->half-open:當服務接口對應的熔斷器狀態爲open狀態時候,所有服務調用方調用該服務方法時候都是執行本地降級方法,那麼什麼時候纔會恢復到遠程調用那?Hystrix提供了一種測試策略,也就是設置了一個時間窗口,從熔斷器狀態變爲open狀態開始的一個時間窗口內,調用該服務接口時候都委託服務降級方法進行執行。如果時間超過了時間窗口,則把熔斷狀態從open->half-open,這時候服務調用方調用服務接口時候,就可以發起遠程調用而不再使用本地降級接口,如果發起遠程調用還是失敗,則重新設置熔斷器狀態爲open狀態,從新記錄時間窗口開始時間。
half-open->closed: 當熔斷器狀態爲half-open,這時候服務調用方調用服務接口時候,就可以發起遠程調用而不再使用本地降級接口,如果發起遠程調用成功,則重新設置熔斷器狀態爲closed狀態。
當請求在規定時間內響應正常,熔斷器處於關閉狀態。
如果有超過50%的請求失敗,即達到閾值,則觸發熔斷(請求次數最少不低於10次),處於open狀態。
close狀態不是永久的,關閉後會進入休眠時間默認是5s,隨後會進入半開狀態,此時,會釋放部分請求通過,若這些請求是健康的,則會完全關閉斷路器,否則繼續保持關閉,再次進入休眠。
默認時長爲1s