目錄
介紹
注: 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