How to achieve resource isolation with Hystrix thread pool technology?

Resource isolation, that is, if you want to isolate all calls to a dependent service in the same resource pool, no other resources will be used, this is called resource isolation. Even for this dependent service, such as commodity service, the simultaneous call volume has reached 1000, but there are only 10 threads in the thread pool, so only these 10 threads will be used to execute the request, not to say, because the interface invocation is delayed, all threads in Tomcat will be exhausted.

By isolating resources, Hystrix provides an abstraction called command. This is Hystrix’s most basic resource isolation technology.

Use HystrixCommand to get a single piece of data

We call the operation of the goods and services through the encapsulation in HystrixCommand, restricted to a key, such as the following GetProductInfoCommandGroup, here we can simply think that this is a thread pool, each call to goods and services, it will only use the thread pool of resources, No more thread resources will be used.

public class GetProductInfoCommand extends HystrixCommand<ProductInfo> { 
	private Long productId; 
	public GetProductInfoCommand(Long productId) { 
		super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoCommandGroup")); 
		this.productId = productId; 
	}
	
	@Override 
	protected ProductInfo run(a) { 
		String url = "http://localhost:8081/getProductInfo? productId=" + productId;
		 
		// Invoke the commodity service interface
		String response = HttpClientUtils.sendGetRequest(url); 
		returnJSONObject.parseObject(response, ProductInfo.class); }}Copy the code

In the cache service interface, we create a command according to productId and execute it to get the commodity data.

@RequestMapping("/getProductInfo") 
@ResponseBody 
public String getProductInfo(Long productId) { 
	HystrixCommand<ProductInfo> getProductInfoCommand = new GetProductInfoCommand(productId); 
	
	// Run the command to obtain the latest commodity data
	ProductInfo productInfo = getProductInfoCommand.execute(); 
	System.out.println(productInfo); return "success"; 
}
Copy the code

This is the execute() method, which is synchronous. You can also call the command queue() method, which simply puts the command into a wait queue in the thread pool, returns immediately, gets a Future object, and then goes on to do something else, It then calls the get() method on the Future some time later to get the data. It’s asynchronous.

2. Use HystrixObservableCommand to obtain data in batches

All commodity data is bound to the same thread pool, which we execute through the HystrixObservableCommand thread, and in this thread, productInfo of productId is pulled back in batches.

public class GetProductInfosCommand extends HystrixObservableCommand<ProductInfo> { 
	private String[] productIds; 
	public GetProductInfosCommand(String[] productIds) { 
		// bind to the same thread pool
		super(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup")); 
		this.productIds = productIds; 
	}
	@Override 
	protected Observable<ProductInfo> construct(a) {
		return Observable.unsafeCreate((Observable.OnSubscribe<ProductInfo>) subscriber -> { 
			for (String productId : productIds) { 
				// Get commodity data in batches
				String url = "http://localhost:8081/getProductInfo? productId="+ productId; String response = HttpClientUtils.sendGetRequest(url); ProductInfo productInfo = JSONObject.parseObject(response, ProductInfo.class); subscriber.onNext(productInfo); }subscriber.onCompleted(); }).subscribeOn(Schedulers.io()); }}Copy the code

In the cache service interface, according to the incoming id list, for example, the id string is separated by Hystrix observablecommand, execute some Hystrix API methods to get all the goods data.

public String getProductInfos(String productIds) { 
	String[] productIdArray = productIds.split(","); 
	HystrixObservableCommand<ProductInfo> getProductInfosCommand = new GetProductInfosCommand(productIdArray); 
	Observable<ProductInfo> observable = getProductInfosCommand.observe(); 
	observable.subscribe(new Observer<ProductInfo>() { 
		@Override 
		public void onCompleted(a) { 
			System.out.println("Got all the commodity data."); 
		}
		@Override 
		public void onError(Throwable e) { 
			e.printStackTrace(); 
		}
		/** * call the method * once the data is retrieved@param productInfo 
		*/ 
		@Override 
		public void onNext(ProductInfo productInfo) { System.out.println(productInfo); }});return "success"; 
}
Copy the code

Let’s step back and look at how Hystrix thread pool technology implements resource isolation.

Since Nginx, caches have been invalidated, so Nginx invokes commodity services through caching services. The default thread size of the cache service is 10, with a maximum of 10 threads calling the interface of the commodity service. Even if the GST fails, up to 10 threads will hang out calling the GST, and the other threads in tomcat that cache the service can be used to call other services and do other things.