雪崩效应
在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC 相互调用。
为了保证其高可用,单个服务通常会集群部署。
由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。
服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应。
为了解决这个问题,业界提出了熔断器模型。
使用的是Spring Cloud里面的 Hystrix
1、服务提供者实现Hystrix
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
在 Application 中增加 @EnableHystrix 注解
@EnableHystrix
@SpringBootApplication
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
Main.main(args);
}
}
在 Service 中增加 @HystrixCommand 注解
在调用方法上增加 @HystrixCommand 配置,此时调用会经过 Hystrix 代理。
@Service(version = "${user.service.version}")
public class UserServiceImpl implements UserService {
@Value("${dubbo.protocol.port}")
private String port;
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
@Override
public String sayHi() {
// return "Hello Dubbo, i am from port:" + port;
throw new RuntimeException("Exception to show hystrix enabled.");
}
}
sayHi方法,抛出异常,而并不是所谓的显示500之类的服务端错误。页面上会显示出异常上显示的信息:Exception to show hystrix enabled。
2、服务消费者实现hystrix
与服务提供者实现hystrix几乎一样,只需要在调用方法上增加 @HystrixCommand 注解,并指定 fallbackMethod 方法
@RestController
public class UserController {
@Reference(version = "${user.service.version}")
private UserService userService;
@HystrixCommand(fallbackMethod = "hiError")
@RequestMapping(value = "hi")
public String sayHi() {
return userService.sayHi();
}
public String hiError() {
return "Hystrix fallback";
}
}
调用hi方法,浏览器会显示Hystrix fallback。而不是500错误
3、熔断器仪表盘
在 Provider 和 Consumer 项目增加 Hystrix 仪表盘功能,两个项目的改造方式相同。
增加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
在 Application 中增加 @EnableHystrixDashboard 注解
@EnableHystrix
@EnableHystrixDashboard
@SpringBootApplication
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
Main.main(args);
}
}
创建 hystrix.stream 的 Servlet 配置
@Configuration
public class HystrixDashboardConfiguration {
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
测试 Hystrix Dashboard
浏览器端访问 http://localhost:9090/hystrix 界面如下: