序言
在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以通過
RPC
互相調用,在 Spring Cloud 中可以用
RestTemplate + Ribbon
和
Feign
來調用。為了保證其高可用,單個服務通常會叢集部署。由于網絡原因或者自身的原因,服務并不能保證 100% 可用,如果單個服務出現問題,調用這個服務就會出現線程阻塞,此時若有大量的請求湧入,
Servlet
容器的線程資源會被消耗完畢,導緻服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成災難性的嚴重後果,這就是服務故障的 “雪崩” 效應。 為了解決這個問題,業界提出了熔斷器模型。
Netflix 開源了 Hystrix 元件,實作了熔斷器模式。
此文章僅限入門 SpringCloud版本為 Greenwich
當然 Hystrix 已經進入維護階段了,也就是說不再會有新功能産出,但是已經足夠成熟。Spring Cloud 正在孵化自己的熔斷器 Resilience4j ,最近阿裡的 Sentinel 也釋出了可用于生産的版本。
使用
首先呢加入如下依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
在yml裡配置一下注冊中心
server:
port: 7001
spring:
application:
name: spring-cloud-action-server-order
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
hostname: localhost
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
然後呢是啟動類
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(ATestApplication.class, args);
}
}
其實還有一個注解可以 同時包含
@EnableDiscoveryClient 、@EnableDiscoveryClient、@EnableHystrix
換成
@SpringCloudApplication
就行了
@SpringCloudApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
在Ribbon中使用
在 Ribbon 調用方法上增加
@HystrixCommand
注解并指定
fallbackMethod
熔斷方法
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "getProductsError")
@GetMapping
public String getOrder() {
return restTemplate.getForObject("http://SPRING-CLOUD-ACTION-SERVER-B/getProducts, String.class);
}
public String getProductsError(String message) {
return "Hi,your request error.";
}
}
怎麼測試呢? 當我關閉
spring-cloud-action-server-product
服務時,通路
@HystrixCommand
注解标注的接口時候,我們發現直接傳回了
getProductsError
裡的内容,就表示服務已經熔斷。
這裡說一點進階用法,如果想使用Hystrix 的詳細配置,可以 使用
@HystrixCommand
将
commandProperties
屬性與
@HystrixProperty
注釋清單一起使用 。
比如設定一個逾時
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "15000")
}
)
或者這樣使用
Hystrix 還而已認證信号量來實作限流,等功能,具體可以在 其 github倉庫的wiki 裡詳細的看到。
Feign 中使用熔斷器
Feign 是自帶熔斷器的,但預設是關閉的。需要在配置檔案中配置打開它,在配置檔案增加以下代碼
feign:
hystrix:
enabled: true
然後在Feign的接口中增加forback指定類
@FeignClient(value = "spring-cloud-action-server-product",fallback =ProductService.FallbackProductService.class )
public interface ProductService {
@GetMapping("/getProducts")
String getProducts();
@Component
class FallbackProductService implements ProductService {
@Override
public String query() {
return "通路出現問題";
}
}
}
然後在調用Feign的時候也就會帶有熔斷的效果啦。
儀表盤
除了隔離依賴服務的調用以外,Hystrix還提供了近實時的監控,Hystrix會實時、累加地記錄所有關于HystrixCommand的執行資訊,包括每秒執行多少請求多少成功,多少失敗等。Netflix通過
hystrix-metrics-event-stream
項目實作了對以上名額的監控。
添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
然後在啟動類中加入
@SpringCloudApplication
@EnableFeignClients
@EnableHystrixDashboard
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
然後加入
HystrixMetricsStreamServlet
的配置
@Configuration
public class HystrixDashboardConfig {
@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:7001/hystrix
就可以啦
輸入相應的玩意設定一下标題就可以進入控制台了,隻要觸發了
Hystrix
熔斷 就會顯示在控制台中。
給一個詳細的說明圖解
什麼情況下會觸發 fallback
方法
fallback
名字 | 描述 | 觸發fallback |
---|---|---|
EMIT | 值傳遞 | NO |
SUCCESS | 執行完成,沒有錯誤 | NO |
FAILURE | 執行抛出異常 | YES |
TIMEOUT | 執行開始,但沒有在允許的時間内完成 | YES |
BAD_REQUEST | 執行抛出HystrixBadRequestException | NO |
SHORT_CIRCUITED | 斷路器打開,不嘗試執行 | YES |
THREAD_POOL_REJECTED | 線程池拒絕,不嘗試執行 | YES |
SEMAPHORE_REJECTED | 信号量拒絕,不嘗試執行 | YES |
fallback
方法在什麼情況下會抛出異常
fallback
名字 | 描述 | 抛異常 |
---|---|---|
FALLBACK_EMIT | Fallback值傳遞 | NO |
FALLBACK_SUCCESS | Fallback執行完成,沒有錯誤 | NO |
FALLBACK_FAILURE | Fallback執行抛出出錯 | YES |
FALLBACK_REJECTED | Fallback信号量拒絕,不嘗試執行 | YES |
FALLBACK_MISSING | 沒有Fallback執行個體 | YES |
注意
Hystrix在執行他的邏輯的時候,其實做了來回的線程切換,是以說很容易導緻一些問題,比如ThreadLocal 或者 Spring 聲明式事物的失效。是以是用需要仔細考慮。
此文章僅限入門,切記啊不會用找不到多去官網看文檔!