HystrixObservableCommand 用在依赖服务返回多个操作结果的时候。它也实现了两种执行方式
-observe():返回Obervable对象,他代表了操作的多个结果,他是一个HotObservable
-toObservable():同样返回Observable对象,也代表了操作多个结果,但它返回的是一个Cold Observable。
package test.hystrix; import com.netflix.hystrix.HystrixCommandGroupKey; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import rx.Observable; import rx.schedulers.Schedulers; /** * HystrixObservableCommand使用示例 * 只需要集成HystrixObservableCommand类,并覆写construct方法即可 * @author Administrator * */ public class UserHystrixObservableCommand extends HystrixObservableCommand<User> { @lombok.Setter @Getter private String[] ids;// 模拟前端的批处理,例如需要删除id为1,2,3,4的记录 public UserHystrixObservableCommand(String[] ids) { super(HystrixCommandGroupKey.Factory.asKey("usercommand"));// 调用父类构造方法 this.ids = ids; } @Override protected Observable<User> construct() { System.out.println(Thread.currentThread().getName()+"is running......"); return Observable.create(new OnSubscribe<User>() { /* * Observable有三个关键的事件方法,分别为onNext,onCompleted,onError,意思很容易懂哈 */ @Override public void call(Subscriber<? super User> observer) { try {// 写业务逻辑,注意try-catch if (!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方法 * 当调用出现异常时,会调用该降级方法 */ @Override public Observable<User> resumeWithFallback() { return Observable.create(new OnSubscribe<User>() { @Override public 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()); } } 调用方 @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>() { @Override public void onCompleted() { System.out.println("聚合完了所有的查询请求!"); System.out.println(list); } @Override public void onError(Throwable t) { t.printStackTrace(); } @Override public void onNext(User user) { list.add(user); } }); return "success"; }
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一次可以发送多条数据返回,从上面的示例可以看出。