资源隔离,就是说,如果把对某一个依赖服务的所有调用请求,全部隔离在同一份资源池内,不会去占用其他资源了,这就叫做资源隔离。
Hystrix进行资源隔离,其实是提供了一个抽象,叫做command。这也是Hystrix最基本的资源隔离技术。
1.利用HystrixCommand获取单条数据
通过将调用商品服务的操作封装到HystrixCommand中,限定一个key,比如下面的GetProductInfoCommandGroup,我们可以简单的认为这是一个线程池,每次调用商品服务,就只会用该线程池中的资源,不会再去用其他线程资源了。
public class GetProductInfoCommand extends HystrixCommand<ProductInfo> {private final Long productId;public GetProductInfoCommand(Long productId) {super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoCommandGroup"));this.productId = productId;}@Overrideprotected ProductInfo run() {System.out.println("hello~!");String url = "http://localhost:8081/product-info?productId=" + productId;// 调用商品服务接口String response = HttpUtil.get(url);return JSONObject.parseObject(response, ProductInfo.class);}}
我们在缓存服务接口中,根据productId创建command并执行,获取到商品数据。
@GetMapping("/product-info")public String getProductInfo(Long productId) {HystrixCommand<ProductInfo> command = new GetProductInfoCommand(productId);// 通过command执行,获取最新商品数据ProductInfo productInfo = command.execute();System.out.println(productInfo);return "success";}
上面执行的是excute()方法,是同步的。也可以对command调用queue()方法,它仅仅将command放入线程池的一个等待队列,就立即返回,拿到一个Future对象,后面可以继续做其他事情,然后过一段时间对Future调用get()方法获取数据,这是异步。
2.利用HystrixObservableCommand批量获取数据
只要是获取商品数据,全部都绑定到同一个线程池里面取,我们通过HystriObservableCommand的一个线程取执行,而在这个线程里面,批量把多个productId的productInfo获取到。
public class GetProductsInfoCommand extends HystrixObservableCommand<ProductInfo> {private final List<Long> productIds;public GetProductsInfoCommand(List<Long> productIds) {// 还是绑定在同一个线程池super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup"));this.productIds = productIds;}@Overrideprotected Observable<ProductInfo> construct() {return Observable.unsafeCreate((Observable.OnSubscribe<ProductInfo>) subscriber -> {for (Long productId : productIds) {// 批量获取商品数据String url = "http://localhost:8081/product-info?productId=" + productId;String response = HttpUtil.get(url);ProductInfo productInfo = JSONObject.parseObject(response, ProductInfo.class);subscriber.onNext(productInfo);}subscriber.onCompleted();}).subscribeOn(Schedulers.io());}}
通过上面的HystrixObservableCommand,执行一些hystrix的API,获取到所有商品数据。
@GetMapping("/products-info")public String getProductsInfo(List<Long> productIds) {GetProductsInfoCommand getProductsInfoCommand = new GetProductsInfoCommand(productIds);Observable<ProductInfo> observe = getProductsInfoCommand.observe();observe.subscribe(new Observer<ProductInfo>() {@Overridepublic void onCompleted() {System.out.println("获取完了所有的商品数据");}@Overridepublic void onError(Throwable e) {e.printStackTrace();}/*** 获取完一条数据,就回调一次这个方法* @param productInfo 商品信息*/@Overridepublic void onNext(ProductInfo productInfo) {System.out.println(productInfo);}});return "success";}

从Nginx开始,缓存都失效了,Nginx通过缓存服务去调用商品服务。缓存服务默认的线程大小是10,最多只有10个线程去调用商品服务的接口。即使商品服务接口故障了,最多也只有10个线程会死在调用商品服务接口的路上,缓存服务的tomcat内其它线程还是可以用来调用其他的服务。
