2.hystrix项目应用之资源隔离




1、pom.xml
添加maven依赖

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>1.5.12</version>
</dependency>


2、将商品服务接口调用的逻辑进行封装


hystrix进行资源隔离,其实是提供了一个抽象,叫做command,就是说,你如果要把对某一个依赖服务的所有调用请求,全部隔离在同一份资源池内


对这个依赖服务的所有调用请求,全部走这个资源池内的资源,不会去用其他的资源了,这个就叫做资源隔离


hystrix最最基本的资源隔离的技术,线程池隔离技术


对某一个依赖服务,商品服务,所有的调用请求,全部隔离到一个线程池内,对商品服务的每次调用请求都封装在一个command里面


每个command(每次服务调用请求)都是使用线程池内的一个线程去执行的


所以哪怕是对这个依赖服务,商品服务,现在同时发起的调用量已经到了1000了,但是线程池内就10个线程,最多就只会用这10个线程去执行


不会说,对商品服务的请求,因为接口调用延迟,将tomcat内部所有的线程资源全部耗尽,不会出现了




3、hystrix资源隔离相关类




HystrixCommand:是用来获取一条数据的
HystrixObservableCommand:是设计用来获取多条数据的




模板:
public class CommandHelloWorld extends HystrixCommand<String> {
    private final String name;
    public CommandHelloWorld(String name) {
//设置要使用的线程池资源名称
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }
    @Override
    protected String run() {
        return "Hello " + name + "!";
    }
}
应用:
public class GetProductInfoCommand extends HystrixCommand<ProductInfo>{


private Long productId;


public GetProductInfoCommand(Long productId) {
super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup"));
this.productId = productId;
}


@Override
protected ProductInfo run() throws Exception {
String url = "http://127.0.0.1:8082/getProductInfo?productId=" + productId;
String response = HttpClientUtils.sendGetRequest(url);
return JSONObject.parseObject(response, ProductInfo.class);  
}


}


模板:
public class ObservableCommandHelloWorld extends HystrixObservableCommand<String> {


    private final String name;


    public ObservableCommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }


    @Override
    protected Observable<String> construct() {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> observer) {
                try {
                    if (!observer.isUnsubscribed()) {
                        observer.onNext("Hello " + name + "!");
                        observer.onNext("Hi " + name + "!");
                        observer.onCompleted();
                    }
                } catch (Exception e) {
                    observer.onError(e);
                }
            }
         } ).subscribeOn(Schedulers.io());
    }
}


应用:
public class GetProductInfosCommand extends HystrixObservableCommand<ProductInfo>{


private String[] productIds;


public GetProductInfosCommand(String[] productIds) {
super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup"));
this.productIds = productIds;
}


@Override
protected Observable<ProductInfo> construct() {
return Observable.create(new Observable.OnSubscribe<ProductInfo>() {


public void call(Subscriber<? super ProductInfo> observer) {
try {
for(String productId : productIds) {
String url = "http://127.0.0.1:8082/getProductInfo?productId=" + productId;
String response = HttpClientUtils.sendGetRequest(url);
ProductInfo productInfo = JSONObject.parseObject(response, ProductInfo.class); 
observer.onNext(productInfo); 
}
observer.onCompleted();
} catch (Exception e) {
observer.onError(e);  
}
}

}).subscribeOn(Schedulers.io());
}


}




4、command的四种调用方式


同步:new CommandHelloWorld("World").execute(),new ObservableCommandHelloWorld("World").observe()


如果你认为observable command只会返回一条数据,那么可以调用上面的模式,去同步执行,返回一条数据


异步:new CommandHelloWorld("World").queue(),new ObservableCommandHelloWorld("World").toObservable()


对command调用queue(),仅仅将command放入线程池的一个等待队列,就立即返回,拿到一个Future对象,后面可以做一些其他的事情,然后过一段时间对future调用get()方法获取数据


HystrixCommand实例(返回单条数据(execute,queue是否同步)):


public String getProductInfo(Long productId) {
// 拿到一个商品id
// 调用商品服务的接口,获取商品id对应的商品的最新数据
// 用HttpClient去调用商品服务的http接口

//1.execute():同步,马上执行
HystrixCommand<ProductInfo> getProductInfoCommand = new GetProductInfoCommand(productId);
ProductInfo productInfo = getProductInfoCommand.execute();

//2.queue():异步,仅仅将command放入线程池的一个等待队列,就立即返回,拿到一个Future对象,
//    后面可以做一些其他的事情,然后过一段时间对future调用get()方法获取数据
// Future<ProductInfo> future = getProductInfoCommand.queue();
// try {
// Thread.sleep(1000); 
// System.out.println(future.get());  
// } catch (Exception e) {
// e.printStackTrace();
// }

System.out.println(productInfo);  
return "success";
}






HystrixObservableCommand实例(返回多条数据(observe,toObservable是否同步)):


public String getProductInfos(String productIds) {
HystrixObservableCommand<ProductInfo> getProductInfosCommand = 
new GetProductInfosCommand(productIds.split(","));  

Observable<ProductInfo> observable = getProductInfosCommand.observe();//马上执行construct()
// Observable<ProductInfo> observable = getProductInfosCommand.toObservable(); // 还没有执行construct()

observable.subscribe(new Observer<ProductInfo>() { // toObservable()等到调用subscribe然后才会执行construct()


public void onCompleted() {
System.out.println("获取完了所有的商品数据");
}


public void onError(Throwable e) {
e.printStackTrace();
}


public void onNext(ProductInfo productInfo) {
System.out.println(productInfo);  
}

});
return "success";
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值