SpringCloud筆記四:互聯網架構服務降級熔斷Hystrix
文章目錄
分佈式核心知識,熔斷降級
系統負載過高,突發流量或者網絡等各種異常情況介紹,常用解決方案
- 熔斷
調用某個服務,如果多次出現調用失敗情況,就會觸發熔斷機制,不允許再調用該服務。
仍能保證該操作能夠執行。比如下單,調用用戶服務,如果用戶服務出現異常,就會觸發熔斷,但是下單功能可以繼續實現。
- 降級
降級就是:當出現網絡等問題時,可以拋棄一些非核心的服務。只返回核心服務數據。例如查詢某個商品時,如果網絡很差,只需要返回該商品的價格,和庫存就可以了。
- 熔斷和降級
相同點:
1、從可用性和可靠性觸發,爲了防止系統崩潰。
2、最終讓用戶體驗到的是某些功能暫時不能用。
不同點:
1、服務熔斷一般是由下游服務故障導致的,而服務降級一般是從整體系統負荷考慮,由調用方控制。
Netflix開源組件斷路器Hystrix
- Hystrix
Hystrix:漢語豪豬的意思,防護,保護的意義。
Hystrix的作用:
在一個分佈式系統裏,一個服務依賴多個服務,可能存在某個服務調用失敗,比如超時、異常等,如何能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,通過Hystrix就可以解決
- Hystrix提供了熔斷,隔離,Fallback,cache、監控等功能。
- 熔斷如何處理
出現錯誤之後可以,fallback 錯誤的信息,兜底數據。
Feign結合Hystrix熔斷開發
- 添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 添加註解,啓動類裏面添加@EnableCircuitBreaker
如果添加的註解過多,可以用@SpringCloudApplication替代一些
- 熔斷降級等處理
最外層api使用,好比異常處理(網絡異常,參數或者內部調用問題
api方法上增加 @HystrixCommand(fallbackMethod=“saveOrderFail”)
編寫fallBack方法實現,方法簽名一定要和api方法簽名一致。即:參數一定要一致。
Feign結合Hystrix斷路器開發
- Feign接口裏面有包含Hystrix的接口方法。但是需要進行配置。
1、在配置文件裏面添加配置,開啓Feign的hystrix的熔斷器
#修改feign請求的超時時間
feign:
#開啓Hystrix熔斷機制
hystrix:
enabled: true
client:
config:
default:
connectTimeout: 2000
readTimeout: 2000
2、創建一個類,用於實現FeignClient,並實現裏面的方法。並被Spring掃描,
該實現類可以寫一些電話通知等功能,用於監控。
@Component
public class ProductClientFallback implements ProductClient {
@Override
public String findById(int id) {
System.out.println("feign 調用product-service findByid異常");
return null;
}
}
3、FeignClient類需要指定失敗後進入的類,fallback=xxx.class
@FeignClient(name = "product-service",fallback = ProductClientFallback.class)
public interface ProductClient {
@GetMapping("api/v1/product/find")
String findById(@RequestParam(value = "id") int id);
}
熔斷降級服務異常報警通知實戰
- 服務異常報警
- 安裝redis
- 導入redis依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置redis
#服務的名稱
spring:
application:
name: order-service
redis:
database: 0
host: 127.0.0.1
port: 6379
timeout: 2000
- 開發報警信息
注意:報警信息一定要new一個線程或者從線程池中獲取一個線程,否則會阻塞下面的代碼。並設置過期時間。注意:api裏面寫一些fallback方法,目的是返回前端一定的沒有調通接口的數據。service裏面的fallback方法,可以沒有任何操作,也可以在控制檯打印一下。
//方法簽名一定要和api中的方法一致
private Object saveOrderFail(int userId,int productId,HttpServletRequest request){
//監控報警
String saveOrderKey="save-order";
String saveValue = redisTemplate.opsForValue().get(saveOrderKey);
final String ip=request.getRemoteAddr();
//可以換成線程池,另外如果是併發的情況下可能會發送多次,可以通過添加鎖的方式解決。
new Thread(()->{
if(StringUtils.isEmpty(saveValue)){
System.out.println("緊急短信,用戶下單失敗,請離開查找原因,ip地址="+ip);
//發送一個http請求,調用短信服務
redisTemplate.opsForValue().set(saveOrderKey,"save-order-fail",20, TimeUnit.SECONDS);
}else{
System.out.println("已經發送過短信,20秒內不重複發送");
}
}).start();
Map<String,Object> msg=new HashMap<>();
msg.put("code",-1);
msg.put("msg","搶購人數太多,您被擠出來了,稍後請重試");
return msg;
}
}
深入源碼剖析Hystrix降級策略和調整
- Hystrix降級策略和調整
查看默認的策略在HystrixCommandProperties中。
1、execution.isolation.strategy 隔離策略
THREAD 線程池隔離
SEMAPHORE 信號量
信號量適用於接口併發量高的情況,如每秒數千次調用情況,導致線程開銷過高,通常只適用於非網絡調用,執行速度快。
2、execution.isolation.thread.timeoutInMilliseconds 超時時間
默認 1000毫秒。
3、execution.timeout.enabled 是否開啓超時限制
4、execution.isolation.semaphore.maxConcurrentRequests 隔離策略爲信號量時,如果達到最大併發數時,後續請求會被拒絕。默認是10
- 調整策略
服務調用存在的時間超時問題:
一個http連接時間超時
一個是請求響應響應時間超時
還有一個請求不響應熔斷超時
如果熔斷超時時間過短,會造成http還未響應就已經進入熔斷機制了。這樣是不可行的,必須讓熔斷時間長一點。
#把hystrix超時時間關閉,默認開啓
hystrix:
command:
default:
execution:
timeout:
enabled: false
一般不允許進行熔斷超時關閉,否則熔斷也就沒有意義了。
配置線程熔斷時間
#設置超時時間爲4s
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
斷路器Dashboard監控儀表盤
- 加入依賴
<!--斷路器監控儀表盤1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!--斷路器監控儀表盤2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 啓動類增加註解
@EnableHystrixDashboard
- 配置文件增加endpoind
#暴露全部的監控信息
management:
endpoints:
web:
exposure:
include: "*"
- 訪問接口
http://localhost:8781/hystrix
Hystrix Dashboard輸入: http://localhost:8781/actuator/hystrix.stream
斷路器監控儀表參數講解和模擬熔斷
- 監控儀器表詳解
- 使用jmeter獲取postmen進行測試