hystrix 简单使用, 以及动态配置更新
概述
只介绍同步模式下简单的使用, 有助于快速接入, 会有一些官方文档中没有涉及的细节.
默认方式
HelloWorld!
public class CommandHelloWorld extends HystrixCommand<String> {
private final String name;
// 构造方法中传入需要用到的数据, run 方法处理逻辑.
public CommandHelloWorld(String name) {
// 构造 Setter 比较麻烦, 后面会进一步介绍
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
// a real example would do work like a network call here
return "Hello " + name + "!";
}
// fallback 方法可选, 如果没有, 默认抛异常.
@Override
protected String getFallback() {
return "fallback";
}
}
构造Setter
Hystrix 讲求的大而全, 设计的比较模式, 用起来不是很方便. 下面是一个构造 Setter 的实例:
Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(site)) // groupKey 对command进行分组, 用于 reporting, alerting, dashboards, or team/library ownership, 也是 ThreadPool 的默认 key
.andCommandKey(HystrixCommandKey.Factory.asKey(site)) // 可以根据 commandKey 具体的运行时参数
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(site)) // 指定 ThreadPool key, 这样就不会默认使用 GroupKey
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter() // 初始化 Command 相关属性
.withMetricsRollingStatisticalWindowInMilliseconds(
100 * 1000) // 设置统计窗口为100秒
.withCircuitBreakerSleepWindowInMilliseconds(
10 * 1000) // 设置熔断以后, 试探间隔为10秒
.withCircuitBreakerRequestVolumeThreshold(
10) // 设置判断熔断请求阈值为10
.withCircuitBreakerErrorThresholdPercentage(
80) // 设置判断熔断失败率为80%
.withExecutionTimeoutInMilliseconds(3 * 1000)) // 设置每个请求超时时间为3秒
.andThreadPoolPropertiesDefaults( // 设置和threadPool相关
HystrixThreadPoolProperties.Setter().withCoreSize(20)); // 设置 threadPool 大小为20(最大20个并发)
另外 threadPool 还有个设置统计窗口的选项, 因为 Hystrix 统计维度会从主线程和线程池两个维度来统计.
还有好多配置信息可以配置, 这里只提供了几个重要的. 其他配置参考:hystrix-configuration
Spring cloud 注解方式
需要用到两个注解: @EnableCircuitBreaker
, @HystrixCommand(fallbackMethod = "reliable")
启动类:
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.web.client.RestTemplate;
@EnableCircuitBreaker
@RestController
@SpringBootApplication
public class ReadingApplication {
@Autowired
private BookService bookService;
@Bean
public RestTemplate rest(RestTemplateBuilder builder) {
return builder.build();
}
@RequestMapping("/to-read")
public String toRead() {
return bookService.readingList();
}
public static void main(String[] args) {
SpringApplication.run(ReadingApplication.class, args);
}
}
服务类:
package hello;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
@Service
public class BookService {
private final RestTemplate restTemplate;
public BookService(RestTemplate rest) {
this.restTemplate = rest;
}
@HystrixCommand(fallbackMethod = "reliable")
public String readingList() {
URI uri = URI.create("http://localhost:8090/recommended");
return this.restTemplate.getForObject(uri, String.class);
}
public String reliable() {
return "Cloud Native Java (O'Reilly)";
}
}
动态更新配置
Hystrix 使用 Archaius
来实现动态配置. 使用 Spring 配置方式:
- 创建配置获取源
- 配置并初始化自动配置
创建配置获取源
实现接口 PolledConfigurationSource
, 并返回一个 Map. 注意 Key 为 hystrix 配置key, 可以参考: Hystrix-configuration
public class DegradeConfigSource implements PolledConfigurationSource {
@Override
public PollResult poll(boolean initial, Object checkPoint) throws Exception {
Map<String, Object> complete = Collections.emptyMap();
// ... init complete map
// complete.put("hystrix.command.<CommandKey>.fallback.enabled"), true); 注意修改对应的 CommandKey
return PollResult.createFull(complete);
}
}
配置并初始化自动配置
创建一个 DynamicConfiguration
, 并注册一下就可以了. 注意, 我们使用了 FixedDelayPollingScheduler
来定期加载新的配置. 默认60秒加载一次.
@Configuration
public class DegradeDynamicConfig {
@Bean
public DynamicConfiguration dynamicConfiguration(@Autowired DegradeConfigSource degradeConfigSource) {
AbstractPollingScheduler scheduler = new FixedDelayPollingScheduler(30 * 1000, 60 * 1000, false);
DynamicConfiguration configuration = new DynamicConfiguration(degradeConfigSource, scheduler);
ConfigurationManager.install(configuration); // must install to enable configuration
return configuration;
}
}
参考
Hystrix-how-to-use
Hystrix-configuration
Hystrix-change-config-dynamically
hystrix-archaius-to-dynamic-config
Spring-circuit-breaker