1.简介
通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等强大功能。
2.联合ribbon
使用
pom
<!--开启断路器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!--开启服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!--开启ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!--开启rrbq消息队列-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
|
applaction
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
|
boostrap.properties
#从配置中心获取配置
spring.application.name=shop
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.failFast=true
#注册为服务
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
|
3.实例(降级服务)
@RestController
public class DcController {
@Autowired
ConsumerService consumerService;
@GetMapping("/consumer")
public String dc() {
return consumerService.consumer();
}
class ConsumerService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "fallback")
public String consumer() {
return restTemplate.getForObject("http://eureka-client/dc", String.class);
}
public String fallback() {
return "fallback";
}
}
}
4.联合feign
使用
pom
<!--开启feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!--开启服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!--开启ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!--开启rrbq消息队列-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
|
applaction
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
|
boostrap.properties
#从配置中心获取配置
spring.application.name=配置中心配置文件名称
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.failFast=true
#注册为服务
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
feign.hystrix.enabled=true//开启降级服务
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000//调整全局超时错误时间,默认1000
hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds //指定CommandKey方法名的超时时间是该值
#线程池
hystrix.threadpool.default.coreSize=10//线程池核心数
#断路器
- hystrix.command.default.circuitBreaker.requestVolumeThreshold=20 //当在配置时间窗口内达到此数量的失败后,进行短路。默认20个)
- hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5 //短路多久以后开始尝试是否恢复,默认5s)
- hystrix.command.default.circuitBreaker.errorThresholdPercentage=50% //出错百分比阈值,当达到此阈值后,开始短路。默认50%)
|
5.降级实例
服务分组+服务+线程池:细粒度实现,一个服务分组中的每一个服务配置一个隔离线程池,为不同的命令实现配置不同的线程池名称即可。
feign
方式一
@FeignClient(name= "factory")/
/要调取服务中心服务名
public interface FactoryClient {
@RequestMapping(method = RequestMethod.POST,value ="/sell",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
Integer sell(@RequestParam(value = "num")Integer num);
@RequestMapping(method = RequestMethod.POST,value ="/create",
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
Integer create(
@RequestParam(value = "num") Integer num);
}
注意:zuul中/shop/**中shop仅对于服务名,**才是调用接口url
|
方式二
@FeignClient(name= "factory",configuration = FactoryHystrix.class)
public interface FactoryClient {
@RequestMapping(method = RequestMethod.POST,value ="/sell",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
Integer sell(@RequestParam(value = "num")Integer num);
@RequestMapping(method = RequestMethod.POST,value ="/create",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
Integer create(@RequestParam(value = "num") Integer num);
}
|
Hystrix
方式一
@Service
public class HystrixClient implements factoryClient {
@Autowired
private FactoryClient factoryClient;
@Override
@HystrixCommand(
groupKey = "factoryGroup",
commandKey ="factory-sell",
threadPoolKey ="http",
fallbackMethod ="fallBackCall")
public Integer sell(@RequestParam(value = "num") Integer num) {
return factoryClient.sell(num);
}
@Override
@HystrixCommand(groupKey = "factoryGroup",commandKey ="factory-create",threadPoolKey ="redis", fallbackMethod ="fallBackCall")
public Integer create(@RequestParam(value = "num") Integer num) {return factoryClient.create(num);}
public Integer fallBackCall(@RequestParam(value = "num") Integer num) {
return -999;
}
}
|
方式二
@Component
public class FactoryHystrix implements FactoryClient{
@Override
@HystrixCommand(groupKey = "factoryGroup",commandKey ="factory-sell",threadPoolKey ="http")
public Integer sell(@RequestParam(value = "num") Integer num) {
return -100;
}
@Override
@HystrixCommand(groupKey = "factoryGroup",commandKey ="factory-create",threadPoolKey ="redis")
public Integer create(@RequestParam(value = "num") Integer num) {return -100;}
}
|
参数解析
名称 | 解释 | 应用 |
groupKey | 服务分组(相同服务用一个名称,如商店) | 服务分组+服务+线程池:细粒度实现,一个服务分组中的每一个服务配置一个隔离线程池,为不同的命令实现配置不同的线程池名称即可。 |
commandKey | 服务业务(服务下面的业务,如购买商品) | 服务分组+线程池:粗粒度实现,一个服务分组/系统配置一个隔离线程池即可,不配置线程池名称或者相同分组的线程池名称配置为一样。 |
threadPoolKey | 配置全局唯一标识线程池的名称,相同线程池名称的线程池是同一个,如果不配置,则默认是分组名,此名字也是线程池中线程名字的前缀(shop.stock) | 混合实现:一个服务分组配置一个隔离线程池,然后对重要服务单独设置隔离线程池。 |
6.配置分析
前言-如何将配置类配置转化为properties配置(HystrixCommandProperties类为例)
1.getProperty(String propertyPrefix, HystrixCommandKey key, String instanceProperty, Boolean builderOverrideValue, Boolean defaultValue) {
propertyPrefix + ".
command." +
key.name() + "." + instanceProperty, builderOverrideValue;
propertyPrefix + ".
command.default." +
instanceProperty, defaultValue;
}
2.protected HystrixCommandProperties(HystrixCommandKey
key, HystrixCommandProperties.Setter builder, String
propertyPrefix) {
this.key = key;
this.circuitBreakerEnabled = getProperty(
propertyPrefix,
key, "
circuitBreaker.enabled", builder.getCircuitBreakerEnabled(), default_circuitBreakerEnabled);
}
3.protected HystrixCommandProperties(HystrixCommandKey key, HystrixCommandProperties.Setter builder) {
this(key, builder, "
hystrix");
}
所以配置开启circuitBreakerEnabled配置:hystrix.command.default.circuitBreaker.enabled=true
HystrixCommandProperties 配置类
- //使用命令调用隔离方式,默认:采用线程隔离,ExecutionIsolationStrategy.THREAD
- private final HystrixProperty<ExecutionIsolationStrategy> executionIsolationStrategy;
- //使用线程隔离时,调用超时时间,默认:1秒
- private final HystrixProperty<Integer> executionIsolationThreadTimeoutInMilliseconds;
- //线程池的key,用于决定命令在哪个线程池执行
- private final HystrixProperty<String> executionIsolationThreadPoolKeyOverride;
- //使用信号量隔离时,命令调用最大的并发数,默认:10
- private final HystrixProperty<Integer> executionIsolationSemaphoreMaxConcurrentRequests;
- //使用信号量隔离时,命令fallback(降级)调用最大的并发数,默认:10
- private final HystrixProperty<Integer> fallbackIsolationSemaphoreMaxConcurrentRequests;
- //是否开启fallback降级策略 默认:true
- private final HystrixProperty<Boolean> fallbackEnabled;
- // 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作.默认:true
- private final HystrixProperty<Boolean> executionIsolationThreadInterruptOnTimeout;
- // 统计滚动的时间窗口,默认:5000毫秒circuitBreakerSleepWindowInMilliseconds
- private final HystrixProperty<Integer> metricsRollingStatisticalWindowInMilliseconds;
- // 统计窗口的Buckets的数量,默认:10个,每秒一个Buckets统计
- private final HystrixProperty<Integer> metricsRollingStatisticalWindowBuckets; // number of buckets in the statisticalWindow
- //是否开启监控统计功能,默认:true
- private final HystrixProperty<Boolean> metricsRollingPercentileEnabled;
- // 是否开启请求日志,默认:true
- private final HystrixProperty<Boolean> requestLogEnabled;
- //是否开启请求缓存,默认:true
- private final HystrixProperty<Boolean> requestCacheEnabled; // Whether request caching is enabled.
- // 熔断器在整个统计时间内是否开启的阀值,默认20秒。也就是10秒钟内至少请求20次,熔断器才发挥起作用
- private final HystrixProperty<Integer> circuitBreakerRequestVolumeThreshold;
- //熔断器默认工作时间,默认:5秒.熔断器中断请求5秒后会进入半打开状态,放部分流量过去重试
- private final HystrixProperty<Integer> circuitBreakerSleepWindowInMilliseconds;
- //是否启用熔断器,默认true. 启动
- private final HystrixProperty<Boolean> +;
- //默认:50%。当出错率超过50%后熔断器启动.
- private final HystrixProperty<Integer> circuitBreakerErrorThresholdPercentage;
- //是否强制开启熔断器阻断所有请求,默认:false,不开启
- private final HystrixProperty<Boolean> circuitBreakerForceOpen;
- //是否允许熔断器忽略错误,默认false, 不开启
- private final HystrixProperty<Boolean> circuitBreakerForceClosed;
命令合并(Collapser)配置
HystrixCollapserProperties,
- //请求合并是允许的最大请求数,默认: Integer.MAX_VALUE
- private final HystrixProperty<Integer> maxRequestsInBatch;
- //批处理过程中每个命令延迟的时间,默认:10毫秒
- private final HystrixProperty<Integer> timerDelayInMilliseconds;
- //批处理过程中是否开启请求缓存,默认:开启
- private final HystrixProperty<Boolean> requestCacheEnabled;
线程池配置
HystrixThreadPoolProperties
- /**
- 配置线程池大小,默认值10个.
- 建议值:请求高峰时99.5%的平均响应时间 + 向上预留一些即可
- */
- HystrixThreadPoolProperties.Setter().withCoreSize(int value)
- /**
- 配置线程值等待队列长度,默认值:-1
- 建议值:-1表示不等待直接拒绝,测试表明线程池使用直接决绝策略+ 合适大小的非回缩线程池效率最高.所以不建议修改此值。
- 当使用非回缩线程池时,queueSizeRejectionThreshold,keepAliveTimeMinutes 参数无效
- */
- HystrixThreadPoolProperties.Setter().withMaxQueueSize(int value)