1. 程式人生 > >每天學點SpringCloud(六):Hystrix使用

每天學點SpringCloud(六):Hystrix使用

artifact 接下來 文件中 系統 lba eureka nal .get com

Hystrix是一個實現斷路器模式的庫。什麽是斷路器模式呢?就像我們家庭中的電閘一樣,如果有那一處出現意外,那麽電閘就會立刻跳閘來防止因為這一處意外而引起更大的事故,直到我們確認處理完那一處意外後才可以再打開電閘。而Hystrix的存在就是為了預防程序中出現這種問題而導致程序不可用的情況。

比如說我們有三個微服務 A、B、C,其中A依賴於B,B依賴於C,如果這時候C出現了問題,那麽就導致B不可用,緊接著A也不可用,更有可能導致整個系統不可用。我們接下來就來看看如何利用Hystrix預防這種情況

創建項目
首先我們復制一份cloud-demo-consumer項目,改名為cloud-demo-consumer-hystrix

引入Hystrix的依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

application.xml不用變
spring:
application:
name: consumer-demo-hystrix
server:
port: 8090
eureka:
client:
healthcheck:
enabled: true
serviceUrl:

defaultZone: http://root:root@localhost:8761/eureka
instance:
prefer-ip-address: true

CloudDemoConsumerApplication改名為CloudDemoConsumerHystrixApplication,並且它的註解應該是@SpringBootApplication
br/>@SpringBootApplication
br/>@EnableCircuitBreake

然後我們看一下controller@RestController
br/>@RestController
public class UserController {

@Autowired
private RestTemplate restTemplate;

@GetMapping("/getUser/{id}")
@HystrixCommand(fallbackMethod = "getUserFallback")
public User getUser(@PathVariable Long id){
     return restTemplate.getForObject("http://provider-demo/user/getUser/"+id,User.class);
}
public User getUserFallback(Long id) {
    User user = new User();
    user.setName("王五");
    return user;
}

}
它相比較於原先的controller僅僅是多了一個@HystrixCommand(fallbackMethod = "getUserFallback")註解和一個方法,這個註解呢就是指定Hystrix在此方法超時時調用的方法。

測試
首先啟動我們代表Eureka服務的項目,然後啟動cloud-demo-provider項目,緊接著啟動我們現在的項目。

項目啟動以後我們打開瀏覽器訪問localhost:8088/user/getUser/2的時候發現一切正常,網頁上返回了張三這個用戶。如果我們沒有引入Hystrix的時候如果這時候把服務提供者停掉的話在訪問會出現什麽情況呢,是不是會報錯,或者超時呀。
但是現在不一樣了,我們引入了Hystrix,所以我們現在停掉提供者訪問的時候會發現程序走了註解指定的fallbackMethod,也就是方法getUserFallBack,這個時候我們瀏覽器得到的結果是王五。

Hystrix默認的超時時間是1秒,也就是說它在等待服務提供者1秒後如果得不到結果的話就會認為提供者掛了,緊接著調用fallbackMethod。
這個時間其實我們可以控制,只需要在yml文件中配置一個屬性就可以自定義這個時間
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 1000 #1000毫秒

Feign的支持
接下來我們看一下Feign是怎麽使用Hystrix,
這次我們改造cloud-demo-consumer-feign項目,項目名稱改為cloud-demo-consumer-feign-hystrix,同樣向上述 方式一樣引入Hystrix的依賴,
接著 CloudDemoConsumerFeignApplication類名改為 CloudDemoConsumerFeignHystrixApplication,同樣的加入@EnableCircuitBreaker註解
有一點不一樣的地方是我們需要在yml文件中配置一下來開啟Hystrix
feign.hystrix.enabled: true

這裏controller中需要改造的不再是指定單個方法,而是指定接口的實現類
@FeignClient(name = "provider-demo", fallback = HystrixClientFallback.class)來看一下這個實現類
@Component
br/>來看一下這個實現類
@Component
br/>@Override
User user = new User();
user.setName("王五");
return user;
}
}

這樣的話如果接口中有多個方法的話我們就不必為每一個方法取指定了。

現在我們已經解決了服務提供者掛掉的事情了,但是有點不好的是,我們現在還不能知道服務提供者到底是咋掛的,要是能捕獲到服務提供者
拋的異常就好了,其實Hystrix對這個是支持的,我們接下來看一下

fallbackFactory

UserFeignClient上方的註解需要變一下
@FeignClient(name = "provider-demo", fallbackFactory = HystrixClientFactory.class)
這次使用的是fallbackFactory這個屬性,我們看一下它指定的這個類又是怎麽實現的呢

@Component
public class HystrixClientFactory implements FallbackFactory<UserFeignClient> {

private static final Logger LOGGER = LoggerFactory.getLogger(HystrixClientFactory.class);

@Override
public UserFeignClient create(Throwable cause) {
    HystrixClientFactory.LOGGER.info("the provider error is: {}", cause.getMessage());
    return new UserFeignClient() {
        @Override
        public User getUser(Long id) {
            User user = new User();
            user.setName("王五");
            return user;
        }
    };
}

}

我們可以看到,在這個create的工廠方法中,它的入參就是服務提供者的異常,得到了這個異常以後才會去做實現。這樣是不是更加靈活了呢?

GitHub:https://github.com/2388386839/spring-cloud-demo
碼雲:https://gitee.com/zhixiang_blog/spring-cloud-demo

如果對您有所幫助,請記得幫忙點一個star哦

本文出自https://zhixiang.org.cn/#/blog/read/4f908c52-4ab9-4261-8189-e76a9fdbcc14,轉載請保留。

每天學點SpringCloud(六):Hystrix使用