轉自:http://www.javashuo.com/article/p-nqbejqdw-gx.htmlhtml
服務熔斷的做用相似於咱們家用的保險絲,當某服務出現不可用或響應超時的狀況時,爲了防止整個系統出現雪崩,暫時中止對該服務的調用。java
服務降級是從整個系統的負荷狀況出發和考慮的,對某些負荷會比較高的狀況,爲了預防某些功能(業務場景)出現負荷過載或者響應慢的狀況,在其內部暫時捨棄對一些非核心的接口和數據的請求,而直接返回一個提早準備好的fallback(退路)錯誤處理信息。這樣,雖然提供的是一個有損的服務,但卻保證了整個系統的穩定性和可用性。git
相同點:github
目標一致 都是從可用性和可靠性出發,爲了防止系統崩潰;web
用戶體驗相似 最終都讓用戶體驗到的是某些功能暫時不可用;spring
不一樣點:api
觸發緣由不一樣 服務熔斷通常是某個服務(下游服務)故障引發,而服務降級通常是從總體負荷考慮;app
管理目標的層次不太同樣,熔斷實際上是一個框架級的處理,每一個微服務都須要(無層級之分),而降級通常須要對業務有層級之分(好比降級通常是從最外圍服務開始); 框架
Hystrix:英 [hɪst'rɪks] 美 [hɪst'rɪks] ,翻譯過來是「豪豬」的意思。 在分佈式環境中,不可避免地會出現某些依賴的服務發生故障的狀況。Hystrix是這樣的一個庫,它經過添加允許時延和容錯邏輯來幫助你控制這些分佈式服務之間的交互。Hystrix經過隔離服務之間的訪問點,阻止跨服務的級聯故障,並提供了退路選項,全部這些均可以提升系統的總體彈性。分佈式
Hystrix的設計目的:
經過第三方客戶端的庫來爲訪問依賴服務時的潛在故障提供保護和控制;
防止在複雜分佈式系統中出現級聯故障;
快速失敗和迅速恢復;
在容許的狀況下,提供退路對服務進行優雅降級;
提供近實時的監控、報警和操做控制;
接下來咱們將經過對《模擬RPC調用(Feign)》一章中的 message-center 項目進行改造,演示如何使用Hystrix,eureka服務註冊中心以及message-service服務提供者無需更改。
在 pom.xml 文件中引入Hystrix依賴:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <properties> <spring-cloud.version>Finchley.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Eureka-Client 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- Feign 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Hystrix 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- SpringCloud 版本控制依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在MessageCenterApplication啓動類上增長@EnableCircuitBreaker註解:
@SpringBootApplication @EnableFeignClients @EnableCircuitBreaker public class MessageCenterApplication { public static void main(String[] args) { new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args); } }
這裏咱們在啓動類中又增長了@EnableCircuitBreaker註解,用來開啓斷路器功能。若是你以爲啓動類上的註解個數有點多的話,可使用一個@SpringCloudApplication 註解來代替@SpringBootApplication(或者@EnableEurekaServer)、@EnableDiscoveryClient、@EnableCircuitBreaker這三個註解。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
接下來,咱們爲MessageCenterController中的getMsg()接口增長斷路器功能,修改部分代碼以下:
@GetMapping("/msg/get") @HystrixCommand(fallbackMethod = "getMsgFallback") public Object getMsg() { String msg = messageService.getMsg(); return msg; } public Object getMsgFallback() { return "祝您 2019 豬年大吉,'豬'事如意!"; }
先啓動Eureka,再啓動一個8771端口的message-service服務,最後啓動message-center。待啓動完成以後,Eureka註冊中心實例註冊信息以下:
此時,訪問 http://localhost:8781/api/v1/center/msg/get ,返回以下結果代表服務調用成功:
而後,停掉message-service服務,再次請求 http://localhost:8781/api/v1/center/msg/get ,返回結果以下:
能夠看出fallback中的信息被直接返回了,代表Hystrix斷路器調用成功。
注意:fallback方法的簽名須要和原方法保持一致。
/** * 獲取消息詳情 */ @GetMapping("/api/v1/msg/detail/{id}") @HystrixCommand(fallbackMethod = "getDetailFallback") public MessageEntity getDetail(@PathVariable(name = "id") Long id) { return messageService.getById(id); } /** * 獲取消息詳情退路 */ public MessageEntity getDetailFallback(Long id){ return null; }
以MessageService的Feign客戶端爲例,爲其添加Hystrix斷路器功能。
經過配置@FeignClient註解的fallback屬性來位MessageServiceClient指定一個自定義的fallback處理類(MessageServiceFallback)。
@FeignClient(name = "message-service", fallback = MessageServiceFallback.class) public interface MessageServiceClient { @GetMapping("/api/v1/msg/get") public String getMsg(); }
MessageServiceFallback須要實現MessageServiceClient接口,而且在Spring容器中必須存在一個該類型的有效Bean。在這裏,咱們使用@Component註解將其注入到Spring容器中。
@Component public class MessageServiceFallback implements MessageServiceClient { @Override public String getMsg() { System.out.println("調用消息接口失敗,對其進行降級處理!"); return "消息接口繁忙,請稍後重試!"; } }
在新版本的Springcloud中,Feign默認關閉了對Hystrix的支持,須要在application.yml進行配置:
feign: hystrix: enabled: true
當message-service服務不可用時,請求 http://localhost:8781/api/v1/center/msg/get,返回結果以下:
查看後臺日誌,打印以下內容,代表fallback方法被成功調用了:
Actuator是Springboot提供的用來對應用系統進行自省和監控的功能模塊,藉助於Actuator開發者能夠很方便地對應用系統某些監控指標進行查看、統計等。
若要使用Actuator對Hystrix 流進行監控,除了需在工程POM文件中引入spring-boot-starter-actuator依賴:
<!-- Actuator 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
還須要在application.yml 中添加以下配置:
management: endpoints: web: exposure: include: hystrix.stream
使用Hystrix一個最大的好處就是它會爲咱們自動收集每個HystrixCommand的信息,並利用Hystrix-Dashboard經過一種高效的方式對每個斷路器的健康狀態進行展現。
值得注意的是,在使用HystrixCommand對RibbonClient進行包裝的時候,你須要確保你配置的Hystrix超時時間要比Ribbon的超時時間長,包括由它們引發的重試時間,舉個例子:若是你的Ribbon鏈接超時時間是1秒,而且Ribbon會連續重試請求3次,那麼你的Hystrix鏈接超時時間須要配置成稍大於3秒。
在 pom.xml 文件中引入Hystrix-Dashboard依賴:
<!-- Hystrix Dashboard 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
在MessageCenterApplication啓動類上增長@EnableHystrixDashboard註解:
@EnableFeignClients @SpringCloudApplication @EnableHystrixDashboard public class MessageCenterApplication { public static void main(String[] args) { new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args); } }
啓動應用,訪問 http://localhost:8781/hystrix ,打開Hystrix-Dashboard監控首頁。
在這裏配置好須要監控的Hystrix流地址 http://localhost:8781/actuator/hystrix.stream ,開始監控。
參考文章
https://github.com/netflix/hystrix/wiki
https://github.com/netflix/hystrix
https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html