Spring Cloud:Hystrix服務降級
背景
在一個複雜的分散式體系中,可能有數十個依賴關係,這些依賴關係在某些時候將不可避免地失敗。
服務雪崩:
多個微服務之間呼叫的時候,服務A呼叫B,B又呼叫C,C又呼叫其他微服務...,在這個鏈路上某個微服務呼叫響應時間過長或者不可用,對A地呼叫會佔用越來越多的系統資源,進而引起系統崩潰,所謂地“服務雪崩”。
Hystrix是一個用於處理分散式系統地延遲和容錯的開源庫,在分散式系統裡,許多依賴不可避免地會呼叫失敗(超時、異常)等,Hystrix能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,避免機連故障,以提高分散式系統的彈性。
"斷路器"本身是一種開關,當某個服務單元發生故障後,通過斷路器的故障監控,向呼叫方返回一個符合預期、可處理的備選響應(FallBack),而不是長時間的等待或者丟擲呼叫方法無法處理的異常
Hystrix重要概念
服務降級fallback
伺服器繁忙,請稍後嘗試,不讓客戶端等待並立即返回一個友好提示,fallback
服務降級情況:
- 程式執行異常
- 超時
- 程式熔斷觸發服務降級
- 執行緒池/訊號量打滿也會導致服務降級
服務熔斷break
類比保險絲達到最大服務訪問後,直接拒絕訪問,拉閘限電,然後呼叫服務降級的方法並返回友好提示。
服務降級->熔斷->恢復呼叫鏈路。
服務限流flowlimit
秒殺高併發等操作,嚴禁一窩蜂過來擁擠,大家排隊,一秒N個,有序進行。
服務端降級初體驗
部分依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
Service方法
@Service public class PaymentService { /** * @Author wen.jie * @Description fallbackMethod中定義了回撥方法 * HystrixProperty中定義了超時時間 * @Date 2020/9/6 13:00 **/ @HystrixCommand(fallbackMethod = "paymentInfo_Handler",commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000") }) public String paymentInfoTimeOut(Integer id){ int time = 5; try { TimeUnit.SECONDS.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } return "執行緒池:"+Thread.currentThread().getName()+" paymentInfoTimeOut"+":"+id; } /** * @Author wen.jie * @Description 服務降級的fallback方法 * @Date 2020/9/6 12:58 **/ public String paymentInfo_Handler(Integer id){ return "執行緒池:"+Thread.currentThread().getName()+" paymentInfoTimeOut"+":"+id+"=====hystrix-handler"; } }
主啟動類上加上@EnableCircuitBreaker
註解或者在主啟動類上直接加上@SpringCloudApplication
@EnableCircuitBreaker
@EnableEurekaClient
@SpringBootApplication
public class PaymentHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class,args);
}
}
啟動服務後,呼叫此方法,發現三秒後呼叫了FallBack方法。
全域性服務降級
在當前類上標註@DefaultProperties(defaultFallback = "paymentIfo_Global_Handler"),表明當前類的FallBack方法,都去找paymentIfo_Global_Handler方法,然後在需要服務降級的方法上只加上@HystrixConmmand就行了
@RestController
@DefaultProperties(defaultFallback = "paymentIfo_Global_Handler")
public class OrderHystrixController {
@Autowired
private PaymentHystrixService paymentHystrixService;
@HystrixCommand
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
public String paymentInfoTimeout(@PathVariable Integer id)
{
return paymentHystrixService.paymentInfoTimeout(id);
}
public String paymentIfo_Global_Handler(){
return "執行緒池:"+Thread.currentThread().getName()+"=====hystrix-handler-order-global";
}
}
執行效果:
但是FallBack混在controller中,有點混亂,且耦合度高。
我們只需要為Feign客戶端定義的介面新增一個服務降級處理的實現類即可實現解耦。
Feign介面:
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallBackService.class)
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfoTimeout(@PathVariable("id") Integer id);
}
服務降級處理的實現類:
@Component
public class PaymentFallBackService implements PaymentHystrixService {
@Override
public String paymentInfoTimeout(Integer id) {
return "PaymentFallBackService--fallback";
}
}
配置yml
feign:
hystrix:
#在feign中開啟hystrix
enabled: true
hystrix:
command:
default: #default全域性有效,service id指定應用有效
execution:
timeout:
#如果enabled設定為false,則請求超時交給ribbon控制,為true,則超時作為熔斷根據
enabled: true
isolation:
thread:
timeoutInMilliseconds: 3000 #斷路器超時時間,預設1000ms