目录
介绍
注: pom.xml和application.properties键“服务容错保护:Spring Could Hystrix”
1 请求命令的创建
1.1 未使用@HystrixCommand注解形式
Hystrix创建通过继承HystrixCommand类来实现。getFallback()方法定义降级错误返回。
public class UserCommand extends HystrixCommand<User> {
@Autowired
private RestTemplate restTemplate;
public UserCommand() {
super(HystrixCommandGroupKey.Factory.asKey("UserCommand"));
}
@Override
protected User run() throws Exception {
System.out.println("");
return restTemplate.getForObject("http://hello-service/user/login",User.class);
}
@Override
protected User getFallback() {
System.out.println("==================================");
System.out.println(getFailedExecutionException().getMessage());
return new User("def","def");
}
}
测试:
1 同步执行:User u = new UserCommand().execute()
2 异步执行:Future<User> fWorld = new UserCommand().queue();
3 通过:Observable实现响应
Observable<User> observe = new UserCommand().observe();
Observable<User> userObservable = new UserCommand().toObservable();
1.2 使用@HystrixCommand注解
@Service("userService")
public class UserService {
/**获取logger实例*/
private final Logger logger = Logger.getLogger(getClass().toString());
@Autowired
private RestTemplate restTemplate;
/**
*同步调用
* @return
*/
@HystrixCommand(fallbackMethod = "notFindFallback1")
public String login()
{
logger.info("调用:http://hello-service/user/login");
// ResponseEntity<String> forEntity = restTemplate.getForEntity("http://hello-service/user/login", String.class);
String forObject = restTemplate.getForObject("http://hello-service/user/login", String.class);
return "我是一个消费者去调用==》"+forObject;
}
/**
*异步调用
* @return
*/
@HystrixCommand(fallbackMethod = "notFindFallback")
public Future<String> loginAsync()
{
return new AsyncResult<String>() {
@Override
public String invoke() {
String forObject = restTemplate.getForObject("http://hello-service/user/login", String.class);
return "我是一个消费者去调用==》"+forObject;
}
};
}
/**
* 异常触发方法
* @return
*/
public String notFindFallback()
{
return "error";
}
/**
* 异常捕获方法,可捕获异常
* @return
*/
public String notFindFallback1(Throwable e)
{
return e.getMessage();
}
}
@HystrixCommand注解属性
1 fallbackMethod指定异常降级方法
2 observableExecutionMode = ObservableExecutionMode.EAGER表示.observe()执行方式observableExecutionMode = ObservableExecutionMode.LAYZ表示.toObservable();
3 ignoreExceptions 指定某类异常触发时,不走fallbackMethod降级方法
4 commandKey 指定命名名,groupKey指定组名,threadPoolKey指定线程。用于划分Hystrix分组,默认同组名化一个线程池组。所以需要指定线程划分。(setter设置)
注:一些情况不需要做降级处理。如写操作,批处理或者离线计算。(操作的返回一般为void)
2 请求缓存
Hystrix提供请求缓存,减轻高并发情况下服务的压力。
2.1 通过重写getCache()方法
继承HystrixCommand类,重写getCacheKey()方法。getCache()方法返回缓存key值。
清理缓存使用HystrixRequestCache.clear()。(getCacheKey()默认返回null,缓存未开启)
2.2 使用缓存注解(必须配合@HystrixCommand使用)
@CacheResult标记结果加入缓存
@CacheRemove请求缓存失效
@CacheKey标记缓存的key
2.2.1 使用@CacheResult实现缓存功能
@CacheResult(cacheKeyMethod = "getCacheKey")
@HystrixCommand(commandKey = "findUserById", groupKey = "UserService", threadPoolKey = "userServiceThreadPool")
public UserVO findById(Long id) {
ResponseEntity<UserVO> user = restTemplate.getForEntity("http://users-service/user?id={id}", UserVO.class, id);
return user.getBody();
}
public String getCacheKey(Long id) {
return String.valueOf(id);
}
2.2.2 使用@CacheResult和@CacheKey实现缓存功能
@CacheResult
@HystrixCommand(commandKey = "findUserById", groupKey = "UserService", threadPoolKey = "userServiceThreadPool")
public UserVO findById2(@CacheKey("id") Long id) {
ResponseEntity<UserVO> user = restTemplate.getForEntity("http://users-service/user?id={id}", UserVO.class, id);
return user.getBody();
}
2.2.3 使用@CacheRemove清空缓存
@CacheRemove(commandKey = "findUserById")
@HystrixCommand(commandKey = "updateUser",groupKey = "UserService",threadPoolKey = "userServiceThreadPool")
public void updateUser(@CacheKey("id")UserVO user){
restTemplate.postForObject("http://users-service/user",user,UserVO.class);
}
请求合并
2 总结
参考:
1 《Spring Could 微服务实战》 翟永超 电子工业出版社 2017.5
参考网站:http://blog.didispace.com/Spring-Cloud基础教程/
https://springcloud.cc