IT之家鴻蒙OS原生版 1.10 上架:重大順暢度優化/滑動切換板塊/支援平板電腦……
Hystrix:服務熔斷
分散式系統面臨的問題
複雜分散式體系結構中的應用程式有數十個依賴關係,每個依賴關係在某些時候將不可避免失敗!
服務雪崩
多個微服務之間呼叫的時候,假設微服務A呼叫微服務B和微服務C,微服務B和微服務C又呼叫其他的微服務,這就是所謂的“扇出”,如果扇出的鏈路上某個微服務的呼叫響應時間過長,或者不可用,對微服務A的呼叫就會佔用越來越多的系統資源,進而引起系統崩潰,所謂的“雪崩效應”。
對於高流量的應用來說,單一的後端依賴可能會導致所有伺服器上的所有資源都在幾十秒內飽和。比失敗更糟糕的是,這些應用程式還可能導致服務之間的延遲增加,備份佇列,執行緒和其他系統資源緊張,導致整個系統發生更多的級聯故障,這些都表示需要對故障和延遲進行隔離和管理,以達到單個依賴關係的失敗而不影響整個應用程式或系統執行
我們需要,棄車保帥!
什麼是Hystrix?
Hystrix是一個應用於處理分散式系統的延遲和容錯的開源庫,在分散式系統裡,許多依賴不可避免的會呼叫失敗,比如超時,異常等,Hystrix 能夠保證在一個依賴出問題的情況下,不會導致整個體系服務失敗,避免級聯故障,以提高分散式系統的彈性。
“斷路器”本身是一種開關裝置,當某個服務單元發生故障之後,通過斷路器的故障監控 (類似熔斷保險絲) ,向呼叫方返回一個服務預期的,可處理的備選響應 (FallBack) ,而不是長時間的等待或者丟擲呼叫方法無法處理的異常,這樣就可以保證了服務呼叫方的執行緒不會被長時間,不必要的佔用,從而避免了故障在分散式系統中的蔓延,乃至雪崩。
Hystrix能幹嘛?
- 服務降級
- 服務熔斷
- 服務限流
- 接近實時的監控
- …
當一切正常時,請求流可以如下所示:
當許多後端系統中有一個潛在阻塞服務時,它可以阻止整個使用者請求:
隨著大容量通訊量的增加,單個後端依賴項的潛在性會導致所有伺服器上的所有資源在幾秒鐘內飽和。
應用程式中通過網路或客戶端庫可能導致網路請求的每個點都是潛在故障的來源。比失敗更糟糕的是,這些應用程式還可能導致服務之間的延遲增加,從而備份佇列、執行緒和其他系統資源,從而導致更多跨系統的級聯故障。
當使用Hystrix包裝每個基礎依賴項時,上面的圖表中所示的體系結構會發生類似於以下關係圖的變化。每個依賴項是相互隔離的
官網資料:https://github.com/Netflix/Hystrix/wiki
服務熔斷
什麼是服務熔斷?
熔斷機制是賭贏雪崩效應的一種微服務鏈路保護機制。
當扇出鏈路的某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的呼叫,快速返回錯誤的響應資訊。檢測到該節點微服務呼叫響應正常後恢復呼叫鏈路。在SpringCloud框架裡熔斷機制通過Hystrix實現。Hystrix會監控微服務間呼叫的狀況,當失敗的呼叫到一定閥值預設是5秒內20次呼叫失敗,就會啟動熔斷機制。熔斷機制的註解是:@HystrixCommand
。
服務熔斷解決如下問題:
- 當所依賴的物件不穩定時,能夠起到快速失敗的目的;
- 快速失敗後,能夠根據一定的演算法動態試探所依賴物件是否恢復。
入門案例
新建springcloud-provider-dept-hystrix-8001模組並拷貝springcloud-provider-dept–8001內的pom.xml、resource和Java程式碼進行初始化並調整。
匯入hystrix依賴
<!--匯入Hystrix依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
調整yml配置檔案
server:
port: 8001
# mybatis配置
mybatis:
# springcloud-api 模組下的pojo包
type-aliases-package: com.haust.springcloud.pojo
# 本模組下的mybatis-config.xml核心配置檔案類路徑
config-location: classpath:mybatis/mybatis-config.xml
# 本模組下的mapper配置檔案類路徑
mapper-locations: classpath:mybatis/mapper/*.xml
# spring配置
spring:
application:
#專案名
name: springcloud-provider-dept
datasource:
# 德魯伊資料來源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
username: root
password: root
# Eureka配置:配置服務註冊中心地址
eureka:
client:
service-url:
# 註冊中心地址7001-7003
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: springcloud-provider-dept-hystrix-8001 #修改Eureka上的預設描述資訊
prefer-ip-address: true #改為true後預設顯示的是ip地址而不再是localhost
#info配置
info:
app.name: haust-springcloud #專案的名稱
company.name: com.haust #公司的名稱
prefer-ip-address: false:
prefer-ip-address: true:
修改controller
/**
* @Description: 提供Restful服務
*/
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 根據id查詢部門資訊
* 如果根據id查詢出現異常,則走hystrixGet這段備選程式碼
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "hystrixGet")
@RequestMapping("/dept/get/{id}")//根據id查詢
public Dept get(@PathVariable("id") Long id){
Dept dept = deptService.queryById(id);
if (dept==null){
throw new RuntimeException("這個id=>"+id+",不存在該使用者,或資訊無法找到~");
}
return dept;
}
/**
* 根據id查詢備選方案(熔斷)
* @param id
* @return
*/
public Dept hystrixGet(@PathVariable("id") Long id){
return new Dept().setDeptno(id)
.setDname("這個id=>"+id+",沒有對應的資訊,null---@Hystrix~")
.setDb_source("在MySQL中沒有這個資料庫");
}
}
為主啟動類新增對熔斷的支援註解@EnableCircuitBreaker
/**
* @Description: 啟動類
*/
@SpringBootApplication
@EnableEurekaClient // EnableEurekaClient 客戶端的啟動類,在服務啟動後自動向註冊中心註冊服務
@EnableDiscoveryClient // 服務發現~
@EnableCircuitBreaker // 新增對熔斷的支援註解
public class HystrixDeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDeptProvider_8001.class,args);
}
}
測試:
使用熔斷後,當訪問一個不存在的id時,前臺頁展示資料如下:
而不適用熔斷的springcloud-provider-dept–8001模組訪問相同地址會出現下面狀況:
因此,為了避免因某個微服務後臺出現異常或錯誤而導致整個應用或網頁報錯,使用熔斷是必要的