Hystrix
开启 eureka-server 单机版注册中心
开启eureka-client 注册hello服务
开启eureka-client-slave 注册hello服务
改造ribbon-consumer 加入hystrix 容错处理
pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
apllication.properties
spring.application.name=hystric-master
server.port= 8002
eureka.client.serviceUrl.defaultZone=http://pear1:9998/eureka
application
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class HystricMasterApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(HystricMasterApplication.class, args);
}
}
controller
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate ;
@Autowired
private ConsumerService consumerService ;
@RequestMapping("/consumerServer")
public String consumerServer() {
return restTemplate.getForEntity("http://SERVER/helloworld?key=ygy",String.class).getBody();
}
@RequestMapping("/consumerClient")
public String consumerClient() {
return consumerService.service();
}
}
service
@Service("consumerService")
public class ConsumerService {
@Autowired
private RestTemplate restTemplate ;
@HystrixCommand(fallbackMethod = "serviceFallBack")
public String service() {
return restTemplate.getForEntity("http://client/getClient?key=client", String.class).getBody();
}
public String serviceFallBack() {
return " service is error ";
}
}
hystix异步获取
eureka client
@GetMapping("/getClientDelay")
public String getClientDelay() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info(" this is eureka client asyn server");
return " hello ,i am eureka client server asyn";
}
hystrix service
@HystrixCommand
public Future<String> serviceAsyn() {
return new AsyncResult<String>() {
@Override
public String invoke() {
return restTemplate.getForEntity("http://client/getClientDelay?key=client", String.class).getBody();
}
};
}
@HystrixCommand
public String serviceSyn() {
return restTemplate.getForEntity("http://client/getClientDelay?key=client", String.class).getBody();
}
hystrix controller
@RequestMapping("/serviceSyn")
public String serviceSyn() {
Date date1=new Date();
String str=consumerService.serviceSyn();
Date date2=new Date();
log.info(" data2 - date 1 = " + ConcurrentDateUtil.diffDate(date1, date2, ConcurrentDateUtil.Type.MILL));
return str;
}
@RequestMapping("/serviceAsyn")
public String serviceAsyn() {
Date date1=new Date();
Future<String> stringFuture=consumerService.serviceAsyn();
Date date2=new Date();
String key=null;
try {
key=stringFuture.get(4000, TimeUnit.MILLISECONDS);
Date date3=new Date();
log.info(" data2 - date 1 = " + ConcurrentDateUtil.diffDate(date1, date2, ConcurrentDateUtil.Type.MILL));
log.info(" data3 - date 2 = " + ConcurrentDateUtil.diffDate(date2, date3, ConcurrentDateUtil.Type.MILL));
} catch (Exception e) {
log.error(" error ", e);
}
return key;
}
输出
2017-08-11 17:15:18.896 INFO 14540 --- [nio-8002-exec-1] test.ygy.ConsumerController : data2 - date 1 = 1180
2017-08-11 17:15:21.669 INFO 14540 --- [nio-8002-exec-2] test.ygy.ConsumerController : data2 - date 1 = 13
2017-08-11 17:15:21.669 INFO 14540 --- [nio-8002-exec-2] test.ygy.ConsumerController : data3 - date 2 = 515
继承实现
子类
/**
* Created by guoyao on 2017/8/12.
*/
public class CustomerCommand extends HystrixCommand<String> {
private RestTemplate restTemplate ;
private String key ;
private String url ;
public CustomerCommand(RestTemplate restTemplate ,String url, String key) {
this(HystrixCommandGroupKey.Factory.asKey("stringGroup"),restTemplate,url,key);
}
public CustomerCommand(HystrixCommandGroupKey groupKey , RestTemplate restTemplate,String url, String key) {
super(groupKey);
this.restTemplate = restTemplate ;
this.url=url;
this.key=key;
}
@Override
protected String run() throws Exception {
return restTemplate.getForEntity(url + key, String.class).getBody();
}
@Override
protected String getFallback() {
return null ;
}
}
service
public String customerSyn(String key) {
CustomerCommand customerCommand=new CustomerCommand(restTemplate,"http://client/getClientDelay?key=", key);
return customerCommand.execute();
}
public Future<String> customerASyn(String key) {
CustomerCommand customerCommand=new CustomerCommand(restTemplate,"http://client/getClientDelay?key=", key);
return customerCommand.queue();
}
controller
@RequestMapping("/serviceSyn")
public String serviceSyn(@RequestParam String key) {
Date date1=new Date();
String str=consumerService.customerSyn(key);
Date date2=new Date();
log.info(" data2 - date 1 = " + ConcurrentDateUtil.diffDate(date1, date2, ConcurrentDateUtil.Type.MILL));
return str;
}
@RequestMapping("/serviceAsyn")
public String serviceAsyn(@RequestParam String key) {
Date date1=new Date();
Future<String> stringFuture=consumerService.customerASyn(key);
Date date2=new Date();
String value=null;
try {
value=stringFuture.get(4000, TimeUnit.MILLISECONDS);
Date date3=new Date();
log.info(" data2 - date 1 = " + ConcurrentDateUtil.diffDate(date1, date2, ConcurrentDateUtil.Type.MILL));
log.info(" data3 - date 2 = " + ConcurrentDateUtil.diffDate(date2, date3, ConcurrentDateUtil.Type.MILL));
} catch (Exception e) {
log.error(" error ", e);
}
return value;
}
observer订阅
自定义
public class CustomerObserverCommand extends HystrixObservableCommand<String> {
private RestTemplate restTemplate;
private String key;
private String url;
public CustomerObserverCommand(RestTemplate restTemplate, String url, String key) {
this(HystrixCommandGroupKey.Factory.asKey("stringGroup"), restTemplate, url, key);
}
public CustomerObserverCommand(HystrixCommandGroupKey groupKey, RestTemplate restTemplate, String url, String key) {
super(groupKey);
this.restTemplate=restTemplate;
this.url=url;
this.key=key;
}
@Override
protected Observable<String> construct() {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
if(!subscriber.isUnsubscribed()){
String value = restTemplate.getForEntity(url + key, String.class).getBody();
subscriber.onNext(value);
subscriber.onNext(value);
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
});
}
}
public String observer(String key) {
StringBuilder result=new StringBuilder();
CustomerObserverCommand observerCommand = new CustomerObserverCommand(restTemplate,"http://client/getClient?key=", key);
Observable<String> observer=observerCommand.observe();
observer.subscribe(new Observer<String>(){
@Override
public void onCompleted() {
log.info(" on completed");
}
@Override
public void onError(Throwable e) {
log.info(" on error ");
e.printStackTrace();
}
@Override
public void onNext(String s) {
result.append(s);
log.info(" on next :" + s );
}
});
return result.toString();
}
2017-08-12 22:12:51.427 INFO 3268 --- [nio-8002-exec-3] test.ygy.ConsumerService : on next : hello ,i am eureka client观察
2017-08-12 22:12:51.427 INFO 3268 --- [nio-8002-exec-3] test.ygy.ConsumerService : on next : hello ,i am eureka client观察
2017-08-12 22:12:51.427 INFO 3268 --- [nio-8002-exec-3] test.ygy.ConsumerService : on completed
基于注解
public String observer(String key) {
StringBuilder result=new StringBuilder();
return observerDo(observerAnnotion(key),result);
}
@HystrixCommand(observableExecutionMode = ObservableExecutionMode.EAGER)
public Observable<String> observerAnnotion(String key) {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
if(!subscriber.isUnsubscribed()){
String value = restTemplate.getForEntity( "http://client/getClientDelay?key="+ key, String.class).getBody();
subscriber.onNext(value);
subscriber.onNext(value);
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
});
}
public String observerDo(Observable<String> observer,StringBuilder result) {
observer.subscribe(new Observer<String>(){
@Override
public void onCompleted() {
log.info(" on completed");
}
@Override
public void onError(Throwable e) {
log.info(" on error ");
e.printStackTrace();
}
@Override
public void onNext(String s) {
result.append(s);
log.info(" on next :" + s );
}
});
return result.toString();
}
请求缓存(只有当前上下文环境)
service
@CacheResult (cacheKeyMethod = "serviceSynCacheKey")
@HystrixCommand (groupKey = "group",threadPoolKey = "poolKey")
public String serviceSyn( String key) {
log.info(Thread.currentThread().getName());
return restTemplate.getForEntity("http://client/getClientDelay?key="+ key, String.class).getBody();
}
public String serviceSynCacheKey(String key) {
return key ;
}
controller
@RequestMapping("/serviceSyn")
public String serviceSyn(@RequestParam String key) {
Date date1=new Date();
String str=consumerService.serviceSyn(key);
Date date2=new Date();
consumerService.serviceSyn(key);
Date date3=new Date();
log.info(" data2 - date 1 = " + ConcurrentDateUtil.diffDate(date1, date2, ConcurrentDateUtil.Type.MILL));
log.info(" data3 - date 2 = " + ConcurrentDateUtil.diffDate(date2, date3, ConcurrentDateUtil.Type.MILL));
return str;
}
webFilter
@WebFilter(filterName = "hystrixContextFilter",urlPatterns = "/*",asyncSupported = true)
public class HystrixFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
chain.doFilter(request, response);
} finally {
context.shutdown();
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
输出
2017-08-13 16:05:51.486 INFO 10524 --- [strix-poolKey-1] test.ygy.ConsumerService : hystrix-poolKey-1
2017-08-13 16:05:51.994 INFO 10524 --- [nio-8002-exec-3] test.ygy.ConsumerController : data2 - date 1 = 522
2017-08-13 16:05:51.994 INFO 10524 --- [nio-8002-exec-3] test.ygy.ConsumerController : data3 - date 2 = 4