在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix类库提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
demo下载地址:https://download.csdn.net/download/qq_22075041/10859685
Hystrix在ribbon中的简单应用在microservice-consumer-movie-ribbon-with-hystrix模块里面
首先pom中添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!--需要此监控依赖,不然启动不起来-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在启动类上面加一个注解:@EnableCircuitBreaker,然后在Controller中这样写:
package com.itmuch.cloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.itmuch.cloud.entity.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/movie/{id}")
//@HystrixCommand属性fallbackMethod中加一个方法叫findByIdFallback,这个方法必须存在,而且返回值要与源方法一致
@HystrixCommand(fallbackMethod = "findByIdFallback")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
}
//就是上面@HystrixCommand(fallbackMethod = "findByIdFallback")
public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}
Hystrix隔离策略相关的参数execution.isolation.strategy设置 ,可以是THREAD或者SEMAPHORE,代码参考microservice-consumer-movie-ribbon-with-hystrix-propagation模块,不配的话是隔离的俩个线程(用户线程、熔断器线程),如果配置为THREAD,意思是运行在一个用户线程。代码如下:
@GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback", commandProperties = @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"))
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
}
public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
return user;
}
查看API监控(需要actuart包的依赖),:
1.在项目启动的路径后面加一个/health。断路器在项目中状态
2.在项目启动的路径后面加一个/health.stream。 监控参数(把这些数据图形化展示的方法在下面)
================================================================================
前面我们讲过Feign了,那他怎么和Hystrix配合使用呢?代码参考:microservice-consumer-movie-feign-with-hystrix模块 @FeignClient注解的属性fallback,定义了一个HystrixClientFallback类,这个类需要实现UserFeignClient接口
package com.itmuch.cloud.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.itmuch.cloud.entity.User;
@FeignClient(name = "microservice-provider-user", fallback = HystrixClientFallback.class)
public interface UserFeignClient {
@RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
public User findById(@PathVariable("id") Long id);
}
package com.itmuch.cloud.feign;
import org.springframework.stereotype.Component;
import com.itmuch.cloud.entity.User;
@Component
public class HystrixClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}
是不是很简单,别忘了需要的依赖,启动类上面加注解哟。
但是这时候我们要禁用单个FeignClient对Hystrix的支持,代码参考:microservice-consumer-movie-feign-customizing-without-hystrix模块。我们给FeignClient2类的的Configuration2中加入了如下配置:
//禁用单个对Hystrix的支持
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
如果要禁用全部,在配置文件中加入:feign.hystrix.enabled=false
=======================================================
接下来我们来聊一下feign使用fallbackFactory属性打印fallback异常,代码参考模块在microservice-consumer-movie-feign-with-hystrix-hystrix-factory里面。
package com.itmuch.cloud.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.itmuch.cloud.entity.User;
//fallback和fallbackFactory都使用的话fallbackFactory不起作用
@FeignClient(name = "microservice-provider-user", /*fallback = HystrixClientFallback.class, */fallbackFactory = HystrixClientFactory.class)
public interface UserFeignClient {
@RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
public User findById(@PathVariable("id") Long id);
}
然后HystrixClientFactory要实现FallbackFactory<UserFeignClient>,其中UserFeignClientWithFactory是UserFeignClient的子接口
package com.itmuch.cloud.feign;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.itmuch.cloud.entity.User;
import feign.hystrix.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("fallback; reason was: {}", cause.getMessage());
return new UserFeignClientWithFactory() {
@Override
public User findById(Long id) {
User user = new User();
user.setId(-1L);
return user;
}
};
}
}
package com.itmuch.cloud.feign;
public interface UserFeignClientWithFactory extends UserFeignClient {
}
==================================================================
Hystrix Dashboard(可视化化监控工具)的使用,代码参考microservice-hystrix-dashboard模块
pom中添加如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
启动类上加注解@EnableHystrixDashboard,然后启动项目,访问路径后面加上/hystrix看到如下界面:
然后把我们前面做过的一个服务地址输进去:
随便起个名字,点进去。就ok了,然后各个代表什么,请自行去官方文档看。。