Hystrix实现服务容错
目录
一、服务容错简介
1.1 为什么要使用服务容错
因为雪崩效应。雪崩效应:在微服务系统中,往往涉及到多个服务的调用。如果一个服务不可用,导致一连串的服务都不可用,从而导致系统崩溃。这种情况称为雪崩效应。
比如: 我们现在由三个服务A,B,C,它们的关系为
A->B->C
A调用B,B调用C。 如果C服务突然不可用,B服务调用C服务失败,B会一直重试,同步等待最后导致B服务资源耗尽,
最终导致B服务不可用。同理,A服务也会变得不可用。这会造成整个系统的瘫痪。
1.2 Hystrix简介
Spring Cloud Hystrix是Spring Cloud提供的,专门为防止雪崩效应的利器。 主要功能有以下几种:1.服务降级
2.服务熔断
3.依赖隔离
4.监控(Hystrix Dashboard)
服务降级
优先核心服务,非核心服务不可用或者弱可用。(通常是在并发量比较高的情况下使用)服务熔断
当某一个服务频繁发生调用错误时,使用服务熔断,可以切断该服务的调用。即在进入Controller逻辑之前,直接调用fallback返回错误。 目的是降低服务器压力。当一定时间之后,再次尝试进行服务调用,如果正常,则恢复使用。依赖隔离
类似Docker中的仓闭模式,Docker使用仓闭模式使得进程之间互不影响。 而Hystrix使用依赖隔离实现了线程池的隔离。对于使用了@HystrixCommand注解的Controller调用, Hystrix会单独为其分配线程池,这样即使某个服务调用过慢,也不会影响其他请求的调用。二、Hystrix的使用
2.1 简单使用案例
比如,我们在订单服务中使用Hystrix1.增加依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.在启动类上增加@EnableCircuitBreaker注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker //启动Hystrix功能
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3.在Controller方法上增加@HystrixCommand注解
具体代码:
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class TestContoller {
//@HystrixCommand 如果不指定defaultFallback,则会使用class中的@DefaultProperties的defaultFallback。
@HystrixCommand(
defaultFallback = "fallback", //启动服务降级措施,如果方法报错,会执行fallback函数。并将fallback的返回值作为该方法的返回值。
commandProperties = { //配置其他的参数
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="2000") //设置超时时间
}
)
@GetMapping("/test")
public String test(){
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/configtest", String.class);
return response;
}
/**
* 调用Controller方法报错时,会进入该方法。
* @return 和HystrixCommand修饰的方法的返回值保持一致。
*/
public String fallback(){
return "当前人数过多,请重试。。";
}
/**
* 当@HystrixCommand注解没有配置“defaultFallback”这一项时,
* 并且class配置了“@DefaultProperties(defaultFallback = "defaultFallback")”这项注解时,
* 如果发生异常,会执行defaultFallback方法,返回defaultFallback的返回值。
* @return
*/
public String defaultFallback(){
return "默认提示:当前人数过多,请重试。。。";
}
}
在Controller方法中增添@HystrixCommand注解,并指定fallback方法,
这样在发生异常时会执行fallback方法,并且将返回fallback方法的返回值。
2.2 服务熔断器的使用
1.Hystrix熔断原理简介这幅图描述了熔断器的工作流程。
初始状态下,熔断器处于关闭(Close)状态。
1.当频发发生异常,熔断器将会进入打开(Open)模式。fail(threshhold reached)
2.经过一定时间,熔断器超时,进入半熔断(Half Open)状态。reset timeout
3.此时,如果http请求成功,则会关闭熔断器。Half Open --(success)–> Close.
4. 如果http请求失败,则会再次打开熔断器。Half Open --(fail)–> Open.
2.改造上面方法,为@HystrixCommand增加一些配置。
@RestController
public class TestContoller {
@HystrixCommand(
defaultFallback = "fallback",
commandProperties = {
@HystrixProperty(name="circuitBreaker.enabled", value="true"), //打开服务熔断机制。
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="10"), //当发生10以上次异常时,启动熔断。
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="10000"), //当开启熔断时,熔断10000毫秒。
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="60") //如果异常的比率大于60,则熔断。
}
)
@GetMapping("/test")
public String test(@RequestParam Integer num){
if(num==1){
throw new RuntimeException("Error");
}else{
return "hello world";
}
}
public String fallback(){
return "当前人数过多,请重试。。";
}
}
使用上述代码。访问
http://localhost:8080/test?num=2
可以正常访问。访问
http://localhost:8080/test?num=1
时发生异常。
当我们频繁访问10次num=1时,最后发现num=2的访问也会异常。
这是因为服务被熔断,等待10s之后,再次访问num2,即恢复正常。
2.3 将HystrixProperty配置到配置文件中
hystrix:
command:
# default默认对不单独进行配置的生效。
default:
# 这里开始是配置内容。对应execution.isolation.thread.timeoutInMilliseconds。
# 如果要配置其他项,同理配置
execution:
isolation:
thread:
timeoutInMilliseconds: 1000 # 配置超时时间
# 单独对某一个方法进行配置。只需要将default改为方法即可。test为要配置的方法名。
test:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 # 配置超时时间
2.4 Feign中使用Hystrix
1.在application.yml增加配置feign:
hystrix:
enabled: true # 激活feign使用hystrix的功能
2.在FeignClient接口类中增添静态子类,并继承该接口
@FeignClient(name="PRODUCT", //name为要访问的服务的名字
fallback = TestClient.TestClientFallBack.class //当产生服务降级,用该类处理。
)
public interface TestClient {
@GetMapping("/test") //要访问的url
String test(); //调用这个方法,即可获取到相应服务的内容。返回值为对方返回的类型。方法名可以自定义。
/**
* 定义该静态子类,并继承TestClient,当发生服务降级时,将会转到该类的对应方法中进行处理。
*/
@Component //一定要把它加上,如果不生效,看是否有扫描到。
public static class TestClientFallBack implements TestClient{
@Override
public String test() {
return "Feign Hystrix";
}
}
}
3.如果没有生效,判断是否TestClientFallBack被扫描到。可以增加@ComponentScan注解,进行包扫描配置。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker //启动Hystrix功能
@ComponentScan(basePackages = "priv.snail") //priv.snail是我的包的根目录
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
三、可视化监控Hystrix Dashboard的使用
1.随便找一个项目中增添依赖,就比如用上面的那个。<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
2.增加@EnableHystrixDashboard注解,开启dashboard功能
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker //启动Hystrix功能
@ComponentScan(basePackages = "priv.snail") //priv.snail是我的包的根目录
@EnableHystrixDashboard //启动Dashboard可视化监控
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3.启动项目,输入http://localhost:8080/hystrix,可以看到如下界面:
这个界面包含三个文本框。
- http://localhost:8080/hystrix.stream 下面有介绍。
Cluster via Turbine (default cluster): http://turbine-hostname:port/turbine.stream
Cluster via Turbine (custom cluster): http://turbine-hostname:port/turbine.stream?cluster=[clusterName]
Single Hystrix App: http://hystrix-app:port/hystrix.stream
2.Delay:更新频率
3.Title: 填监控的服务名就行。
注意:
高版本中,应该使用http://localhost:8080/application/hystrix.stream
因为高板本中的
management.context-path: /application
这个配置。高版本将默认路径加了个application
4.进入之后,会看到另一个页面。如图所示:
这里会显示出各个接口的调用情况。
这个数字的具体意思可以根据颜色来判断。图少截取了一部分。右上角由数字的具体意思。
大概包含以下几种
Success | Short-Circuited | Bad Request | Timeout | Rejected | Failure | Error %