Introduction
In the high concurrency scenario, Hystrix provides the function of request caching, which can be easily opened and used to optimize the system, so as to reduce the consumption of request threads and the response time of requests in high concurrency. Friends who are willing to know the source code ask for communication and sharing technology directly: 21477 75633
Second, turn on request caching function
When implementing HystrixCommand or HystrixObservableCommand, the request cache is opened by overloading getCacheKey().
For example:
public class CommandUsingRequestCache extends HystrixCommand<Boolean> { private final int value; protected CommandUsingRequestCache(int value) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.value = value; } @Override protected Boolean run() { return value == 0 || value % 2 == 0; } //By caching the key value of the request returned from the getCacheKey method, the request command can be cached. When different external requests occur //When the processing logic invokes the same dependent service, Hystrix distinguishes whether a duplicate request is based on the value returned by the getCacheKey method. //If their cachekey s are the same, then the dependent service value is actually called once when the first request arrives, and the other one //The request returns the result directly from the request cache, so opening the cache has the following advantages: //Reduce the number of duplicate requests and the concurrency of dependent services //In the context of the same user request, the return data of the same dependent service is always consistent. //Request caching takes effect before run() and construct() are executed, so unnecessary thread overhead can be effectively reduced. @Override protected String getCacheKey() { return String.valueOf(value); } }
3. Cleaning Failure Cache Function
When using request caching, if only read operation, then it is not necessary to consider whether the cache content is correct, but if there is an operation to update the data in the request command, then the data in the cache needs to be processed in time when we write to prevent the request command of read operation from obtaining invalid data.
In Hystrix, the cache can be cleaned up by the HystrixRequestCache.clear () method.
For example:
//When we implement the request cache for the GetterCommand command, it is imperative to clean the cache for the SetterCommand command to ensure that //After the prefixStoredOnRemoteDataStore is updated, the result of the same cache in the Hystrix request cache is removed, so that the next time according to id //When prefixStoredOnRemoteDataStore is retrieved, data is not retrieved from the cache public class CommandUsingRequestCacheInvalidation { /* represents a remote data store */ private static volatile String prefixStoredOnRemoteDataStore = "ValueBeforeSet_"; //Getting data based on id public static class GetterCommand extends HystrixCommand<String> { private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("GetterCommand"); private final int id; public GetterCommand(int id) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetSetGet")) .andCommandKey(GETTER_KEY)); this.id = id; } @Override protected String run() { return prefixStoredOnRemoteDataStore + id; } @Override protected String getCacheKey() { return String.valueOf(id); } //This method retrieves commands from the default Histrix concurrency policy based on GETTER_KEY for an instance of the request cache object Hystrix RequestCache //Then call the clear method of the request cache object to clean up the cache content whose Key is the id value. public static void flushCache(int id) { HystrixRequestCache.getInstance(GETTER_KEY, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id)); } } //Values for updating prefixStoredOnRemoteDataStore public static class SetterCommand extends HystrixCommand<Void> { private final int id; private final String prefix; public SetterCommand(int id, String prefix) { super(HystrixCommandGroupKey.Factory.asKey("GetSetGet")); this.id = id; this.prefix = prefix; } @Override protected Void run() { // persist the value against the datastore prefixStoredOnRemoteDataStore = prefix; //After calling the prefixStoredOnRemoteDataStore, add the GetterCommand //The static method flushCache is invoked to clean up the time cache. GetterCommand.flushCache(id); // no return value return null; } } }
The code structure is as follows: Data and Source Sources