Hystrix系列-2-HystrixObservableCommand的使用

来源:互联网 发布:ati hd 4850 mac 编辑:程序博客网 时间:2024/06/06 09:33

在前面一节中HystrixCommand的使用,下面,我们来介绍HystrixObservableCommand的使用。HystrixObservableCommand的作用仍然是用来做资源隔离的,后面会介绍和HystrixCommand的区别,先看用法,示例代码如下:

/** * HystrixObservableCommand使用示例 * 只需要集成HystrixObservableCommand类,并覆写construct方法即可 * @author Administrator * */public class UserHystrixObservableCommand extends HystrixObservableCommand<User> {@lombok.Setter@Getterprivate String[] ids;// 模拟前端的批处理,例如需要删除id为1,2,3,4的记录public UserHystrixObservableCommand(String[] ids) {super(HystrixCommandGroupKey.Factory.asKey("usercommand"));// 调用父类构造方法this.ids = ids;}@Overrideprotected Observable<User> construct() {System.out.println(Thread.currentThread().getName()+"is running......");return Observable.create(new OnSubscribe<User>() {/* * Observable有三个关键的事件方法,分别为onNext,onCompleted,onError,意思很容易懂哈 */@Overridepublic void call(Subscriber<? super User> observer) {try {// 写业务逻辑,注意try-catchif (!observer.isUnsubscribed()) {for (String id : ids) {CloseableHttpClient client = HttpClients.createDefault();HttpGet get = new HttpGet("http://localhost:7901/user/" + id);CloseableHttpResponse response = client.execute(get);HttpEntity entity = response.getEntity();String body = EntityUtils.toString(entity);ObjectMapper mapper = ObjectMapperInstance.getInstance();User u = mapper.readValue(body, User.class);//TimeUnit.SECONDS.sleep(3);observer.onNext(u);}observer.onCompleted();}} catch (Exception e) {observer.onError(e);}}}).subscribeOn(Schedulers.io());}/** * fallback方法的写法,覆写resumeWithFallback方法 * 当调用出现异常时,会调用该降级方法 */@Overridepublic Observable<User> resumeWithFallback() {return Observable.create(new OnSubscribe<User>() {@Overridepublic void call(Subscriber<? super User> observer) {try {if (!observer.isUnsubscribed()) {User u = new User();u.setUsername("刘先生");u.setId(1l);observer.onNext(u);observer.onCompleted();}} catch (Exception e) {observer.onError(e);}}}).subscribeOn(Schedulers.io());}}
Controller的代码如下:

@RestControllerpublic class UserController {@RequestMapping("/user/{id}")public User getUser(@PathVariable("id") String id){HystrixCommand<User> userCommand = new UserHystrixCommond(id);return userCommand.execute();}@RequestMapping("/userf/{id}")public User getUserFallback(@PathVariable("id") String id){HystrixCommand<User> userCommand = new UserHystrixCommondWithFallback(id);return userCommand.execute();}@RequestMapping("/users/{ids}")public String getAll(@PathVariable("ids") String ids){List<User> list = new ArrayList<User>();UserHystrixObservableCommand observableCommand = new UserHystrixObservableCommand(ids.split("-"));Observable<User> observe = observableCommand.observe();observe.subscribe(new Observer<User>() {@Overridepublic void onCompleted() {System.out.println("聚合完了所有的查询请求!");System.out.println(list);}@Overridepublic void onError(Throwable t) {t.printStackTrace();}@Overridepublic void onNext(User user) {list.add(user);}});return "success";}}

调用结果如下:

http-nio-8080-exec-2is running......2017-06-15 17:07:08.097 DEBUG 652 --- [nio-8080-exec-2] o.s.b.w.f.OrderedRequestContextFilter    : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@1afa51c聚合完了所有的查询请求![User(id=1, username=张三, address=北京, age=21), User(id=2, username=李四, address=上海, age=25), User(id=3, username=王五, address=武汉, age=22), User(id=4, username=马六, address=成都, age=28)]

当把下面这行代码打开时,就会调用降级方法:

//TimeUnit.SECONDS.sleep(3);// 默认的超时时间为1000ms,此处休眠3s,就会抛异常,进入降级方法
测试结果如下:

http-nio-8080-exec-1is running......2017-06-15 17:10:14.193 DEBUG 3660 --- [nio-8080-exec-1] o.s.b.w.f.OrderedRequestContextFilter    : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@1820f272017-06-15 17:10:14.201 DEBUG 3660 --- [nio-8080-exec-2] o.s.b.w.f.OrderedRequestContextFilter    : Bound request context to thread: org.apache.catalina.connector.RequestFacade@1820f272017-06-15 17:10:14.219 DEBUG 3660 --- [nio-8080-exec-2] o.s.b.w.f.OrderedRequestContextFilter    : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@1820f27聚合完了所有的查询请求![User(id=1, username=刘先生, address=null, age=0)] // 降级方法返回

下面,我们来和HystrixCommand进行比较:

1、HystrixCommand提供了同步和异步两种执行方式,而HystrixObservableCommand只有异步方式

2、HystrixCommand的run方法是用内部线程池的线程来执行的,而HystrixObservableCommand则是由调用方(例如Tomcat容器)的线程来执行的,因为是异步,所以两种方式都能很好的起到资源隔离的效果。这点也可以从前面的测试结果中看出,当调用HystrixCommand的run方法时,控制台输出执行线程为:hystrix-usercommand-1is running......,而HystrixObservableCommand的控制台输出线程为:http-nio-8080-exec-1is running......

3、HystrixCommand一次只能发送单条数据返回,而HystrixObservableCommand一次可以发送多条数据返回,从上面的示例可以看出。

原创粉丝点击