1.声明
当前的内容主要用于本人学习和复习之用,当前的内容包括使用Hystrix这个熔断器,改造前面的Eureka的demo,实现服务熔断操作(主要来源:Spring Cloud官方的demo
)
Hystrix熔断器的个人理解
就是在超市买东西的时候,发现要买的东西不无货或者下架了(但是必须购买),这个时候我们直接购买相同的产品(这个就是熔断,或者返回不能购买的信息)
之前的demo为:添加了Ribbon的demo
为当前的AppDemo和PermissServiceApp这两个项目所在的pom文件中添加熔断器的依赖
<!-- 注入熔断器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.修改当前的AppDemo
直接将前面的AppDemo中的controller中的内容提取出来变成
AppDemo中的内容:
@EnableCircuitBreaker // 启动熔断器
@EnableDiscoveryClient
@SpringBootApplication
public class AppDemo {
@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(AppDemo.class, args);
}
}
AppController中的内容
@RestController
public class AppController {
@Autowired
RestTemplate restTemplate;
private static final String SUFIX_STRING = "-service-provider";
private static final String PREFIX_STRING = "http://";
String getLoadBalancedUrl(String serviceName, String restUrl) {
return new StringBuffer(PREFIX_STRING).append(serviceName).append(SUFIX_STRING).append(restUrl).toString();
}
/*
* @Autowired DiscoveryClient client;
*/
// 为该方法采用熔断器
@HystrixCommand(fallbackMethod = "timeOut", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") })
@RequestMapping("/getPermiss")
public String getPermiss(String roleName) {
System.out.println("访问App门面中通过角色名称获取用户权限");
return restTemplate.getForEntity(getLoadBalancedUrl("permiss", "/getPermissByRoleName?roleName={1}"),
String.class, roleName).getBody();
}
public String timeOut(String roleName) {
System.out.println("访问超时-->" + roleName);
return "当前访问权限操作,超时了,请过一段时间访问!";
}
@RequestMapping("/getUserInfo")
// 用户信息模块
public String getUserInfo(String name) {
System.out.println("访问App门面中通过用户名称获取用户信息");
ResponseEntity<String> postForEntity = restTemplate
.getForEntity(getLoadBalancedUrl("userinfo", "/getUserInfoByName?name={1}"), String.class, name);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/login")
public String login(String username) {
System.out.println("访问App门面中通过用户名称来检查登录");
ResponseEntity<String> postForEntity = restTemplate
.getForEntity(getLoadBalancedUrl("userinfo", "/login?name={1}"), String.class, username);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/register")
public String register(String name) {
System.out.println("访问App门面中注册用户信息");
ResponseEntity<String> postForEntity = restTemplate
.getForEntity(getLoadBalancedUrl("register", "/registerUserInfo?name={1}"), String.class, name);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/pay")
public String pay(String name, Integer money) {
System.out.println("访问App门面中支付服务");
ResponseEntity<String> postForEntity = restTemplate
.getForEntity(getLoadBalancedUrl("pay", "/pay?name={1}&money={2}"), String.class, name, money);
String body = postForEntity.getBody();
return body;
}
}
3.开始测试熔断器
首先开启服务注册中心,然后启动AppDemo和PermissServiceApp这两个,等待启动成功后开始访问
访问成功!
测试熔断器的作用,直接将启动的PermissServiceApp这个程序关闭掉
,再次访问门户AppDemo的结果为:
操作结果成功
4.测试让线程休眠方式导致熔断
在当前的AppController 中的getPermiss方法中的最前面加入以下代码
Random random = new Random();
try {
Thread.sleep(random.nextInt(3000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
由于这里设定的是2秒超时时间(默认也是2秒),此时访问容易熔断并出现异常
5.使用异步方式执行(前面是同步方式)
直接使用restTemplate方式访问并返回结果,该操作是同步方式执行,使用异步方式执行需要使用Future来实现
Future<String> asyncResult = new AsyncResult<String>() {
@Override
public String invoke() {
return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
}
};
String result = null;
try {
result = asyncResult.get();
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return result;
通过测试发现这里极易发生熔断
6.为当前具有@Hystrix的客户端添加和查看仪表盘
1.为当前的AppDemo这个项目添加pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
2.为当前的AppDemo这个项目的入口类添加@EnableHystrixDashboard //开启熔断器仪表盘
3.访问当前的监控地址:http://localhost:2008/hystrix
4.添加本地当前AppDemo的监控,直接添加http://localhost:2008/hystrix.stream
5.查看结果
7.总结
1.Hystrix的使用非常简单,只需要在需要使用的地方添加pom依赖即可,在入口类中添加@EnableCircuitBreaker开启熔断器,然后在哪个可能出现熔断的地方添加@Hystrix,并创建熔断后调用的方法,注意方法参数类型必须完全一致
2.熔断主要是因为在访问的时候,提供服务的地址服务宕机、出现异常、响应超时等出现的
3.开启熔断仪表盘,只需要添加配置文件,然后再需要开启熔断器的入口类中添加@EnableHystrixDashboard
,然后既可以访问http://当前熔断器所在的ip地址:端口/hystrix
4.可以将指定的端口添加如仪表盘中
以上纯属个人见解,如有问题请联本人!