1.pom.xmlhtml
<dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>1.5.12</version> </dependency>
二、將商品服務接口進行command封裝tomcat
hystrix進行資源隔離其實就是提供了一個抽象,叫作command,也就是說,若是要把對某一個依賴服務的全部調用請求,所有隔離在同一份資源池內;對這個依賴服務的全部調用請求,所有走這個資源池內的資源,不會去用其餘的資源了,這個就叫作資源隔離。網絡
hystrix最基本的資源隔離的技術,線程池隔離技術;對某一個依賴服務,好比商品服務,全部的調用請求,所有隔離到一個線程池內,對商品服務的每次調用請求都封裝在一個command裏面;每一個command(每次服務調用請求)都是使用線程池內的一個線程去執行的app
因此哪怕是對這個依賴服務,也就是商品服務,若是一瞬間同時發起的調用量已經到了1000個請求了,可是若是線程池內就10個線程,那麼最多就只會用這10個線程去執行;所以就不會出現由於對商品服務接口調用延遲,致使將tomcat內部全部的線程資源所有耗盡。異步
public class GetProductInfoCommand extends HystrixCommand<ProductInfo> { private Long productId;
private ProductService productService; public GetProductInfoCommand(Long productId,ProductService productService) { super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup")); this.productId = productId;
this.productService = productService; } @Override protected ProductInfo run() throws Exception { ProductInfo p = productService.findProductById(productId);return p; } }
public class GetProductInfosCommand extends HystrixObservableCommand<ProductInfo> { private String[] productIds;
prvivate ProductService productService; public GetProductInfosCommand(String[] productIds,ProductService productService) { super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup")); this.productIds = productIds;
this.productService = productService; } @Override protected Observable<ProductInfo> construct() { return Observable.create(new Observable.OnSubscribe<ProductInfo>() { public void call(Subscriber<? super ProductInfo> observer) { try { for(String productId : productIds) { ProductInfo p = productService.findProductById(productId); observer.onNext(p); } observer.onCompleted(); } catch (Exception e) { observer.onError(e); } } }).subscribeOn(Schedulers.io()); } }
三、command接口ide
HystrixCommand:發射單個操做結果
HystrixObservableCommand:發射多個操做結果this
所謂「發射」,你們能夠理解爲 使用回調方法,發射屢次,意味着能夠屢次調用回調方法,好比:spa
一、若是返回了一個List,咱們又想把List裏的每一個對象都處理一下.net
二、再或者咱們的實現裏調用了多個服務,能夠每一個服務的結果都處理一下等。。。線程
關於這兩個接口的區別,網絡上幾乎都是這個意思,若是想加深理解,下面是stack 的截圖
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 { observer.onNext("Hello " + name + "!"); observer.onNext("Hi " + name + "!"); observer.onCompleted(); } catch (Exception e) { observer.onError(e); } } } ).subscribeOn(Schedulers.io()); }
}
@Autowired
private ProductService productService;
@RequestMapping("/getProductInfo") @ResponseBody public String getProductInfo(Long productId) { HystrixCommand<ProductInfo> getProductInfoCommand = new GetProductInfoCommand(productId,productSerive); ProductInfo productInfo = getProductInfoCommand.execute(); System.out.println(productInfo); return "success"; } /** * 一次性批量查詢多條商品數據的請求 */ @RequestMapping("/getProductInfos") @ResponseBody public String getProductInfos(String productIds) { HystrixObservableCommand<ProductInfo> getProductInfosCommand = new GetProductInfosCommand(productIds.split(","),productService); Observable<ProductInfo> observable = getProductInfosCommand.observe(); // observable = getProductInfosCommand.toObservable(); // 尚未執行 observable.subscribe(new Observer<ProductInfo>() { // 等到調用subscribe而後纔會執行 public void onCompleted() { System.out.println("獲取完了全部的商品數據"); } public void onError(Throwable e) { e.printStackTrace(); } public void onNext(ProductInfo productInfo) { System.out.println(productInfo); } }); return "success"; }
四、command的四種調用方式
同步:new CommandHelloWorld("World").execute(),new ObservableCommandHelloWorld("World").toBlocking().toFuture().get()
若是你認爲observable command只會返回一條數據,那麼能夠調用上面的模式,去同步執行,返回一條數據
異步:new CommandHelloWorld("World").queue(),new ObservableCommandHelloWorld("World").toBlocking().toFuture()
對command調用queue(),僅僅將command放入線程池的一個等待隊列,就當即返回,拿到一個Future對象,後面能夠作一些其餘的事情,而後過一段時間對future調用get()方法獲取數據
Observable<String> fWorld = new CommandHelloWorld("World").observe();// 當即執行 fWorld.subscribe(new Observer<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(String v) { System.out.println("onNext: " + v); } }); Observable<String> fWorld = new ObservableCommandHelloWorld("World").toObservable();//延遲執行,調用subscribe()時候再執行 fWorld.subscribe(new Observer<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(String v) { System.out.println("onNext: " + v); } });
好文推薦:
https://www.cnblogs.com/happyflyingpig/p/8079308.html