Netflix Hystrix
在分布式环境中,服务之间的调用不可避免地有部分会失败。Hystrix是一个用来控制分布式服务之间的交互的框架,它提供了延迟容忍和错误容忍机制。它隔离服务之间的访问点,阻断服务之间的级联失败,提供熔断配置选项。
运行机制
将所有对外部系统的调用封装为一个HystrixCommand或HystrixObservableCommand实例,每个command通常在一个独立的线程中执行;
超出执行时间阈值的请求会超时;
为每个调用维护一个线程池(或信号量);如果线程池或信号量已满,新到达的请求会被立即拒绝而不是排队;
统计成功,失败,超时,线程拒绝;
当对服务的请求发生错误的百分比超过设定的阈值时,手动或自动打开断路器一段时间,阻断对某个服务的所有请求;
当请求失败,执行熔断逻辑(拒绝请求,或超时,或短路);
监控运行指标和配置变更;
Hystrix提供了2种隔离策略:线程池隔离和信号量隔离。默认使用线程池隔离。
Hystrix常用配置参数:
CommandKey: 一个HystrixCommand的唯一标记,用于监控、熔断、metrics统计、缓存等;
GroupKey: 用于对HystrixCommand进行分组。默认为类名;
ThreadPoolKey: 线程池的唯一标记,默认为类名
一个CommandKey对应一份Hystrix配置,一个ThreadPoolKey对应一个线程池
使用示例
Spring Cloud Netflix集成了Hystrix, 开发中可引入以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
/**
* Hello world!
*
*/
@EnableHystrix
@SpringBootApplication
public class HelloHystrixApplication
{
public static void main( String[] args )
{
SpringApplication.run(HelloHystrixApplication.class, args);
}
}
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class HystrixController {
@HystrixCommand(commandKey = "hello", fallbackMethod = "fallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "0"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
})
@GetMapping("/hello1")
public String hello1() {
return new RestTemplate().getForObject("https://httpbin.org/status/200", String.class);
}
@HystrixCommand(commandKey = "hello", fallbackMethod = "fallback")
@GetMapping("/hello2")
public String hello2() {
return new RestTemplate().getForObject("https://httpbin.org/status/200", String.class);
}
@HystrixCommand(threadPoolKey = "singleThread", fallbackMethod = "fallback",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "1")
})
@GetMapping("/singleThread")
public String singleThread() {
System.out.println("--" + Thread.currentThread().getName());
return new RestTemplate().getForObject("https://httpbin.org/status/200", String.class);
}
@HystrixCommand(threadPoolKey = "singleThread", fallbackMethod = "fallback")
@GetMapping("/singleThread2")
public String singleThread2() {
System.out.println("--" + Thread.currentThread().getName());
return new RestTemplate().getForObject("https://httpbin.org/status/200", String.class);
}
@HystrixCommand(fallbackMethod = "fallback")
@GetMapping("/multipleThread")
public String multipleThread() {
System.out.println("--" + Thread.currentThread().getName());
return new RestTemplate().getForObject("https://httpbin.org/status/200", String.class);
}
public String fallback(Throwable throwable) {
String fallbackMsg = "Hystrix fallback";
System.out.println("exception : " + throwable);
return fallbackMsg;
}
}
参考:Home · Netflix/Hystrix Wiki · GitHub
<<深入理解Spring Cloud与实战>>