For those resources that are cachable, especially when we have a high latency target system, how do we "preheat" the response cache?
It depends on your usecase and how caching is implemented in your proxy -
Lets take a simple case of a weather proxy - and lets say you use Response cache policy to cache weather response by zip code.
Easiest way to load entries to the cache is to actually send (load) requests to your API as your clients would make - it automatically populates the cache
From analytics standpoint, if you want to differentiate the actual traffic from the traffic that was used to 'warm' your cache - you could probably use a customer variable in your flow to do that
Alternatively, you could have dedicated flows to populate the cache -- these flows would use the same cache resource and keys -- so normal API calls , when it happens, would find the responses in the cache
+ Predictive caching ?
Load the response of other API calls assuming they will be called next when the first API call gets executed and if the quota.used = 0 so that you don't need to pre-populate using external triggers but depends on use case though .
We have implemented a fire and forget JSC policy for one of our customers that reads a list of URLs from KVM, calling these URLs results in populating the response cache. This Javascript callout is run on the back of a user authentication call and results in frequently accessed data being available from cache later in the user journey.
A couple notes about this implementation:
Here is a sample of JSC code for realizing this:
var request, preheatSets = JSON.parse(context.getVariable("preheatConfig")), sync = context.getVariable("request.queryparam.sync"); preheatSets.forEach(function(set) { processSet(set, sync); }); function processSet(set, sync) { if (set) { //now we want to do the variable substitutions var variables = getVariables(set.url); variables.forEach(function(variable) { var value = context.getVariable(variable); if (value) set.url = set.url.replace("{" + variable + "}", value); }); //now do the same thing for each header var requestHeaders = {}; set.headers.forEach(function(header) { var variables = getVariables(header.value); variables.forEach(function(variable) { var value = context.getVariable(variable); if (value) header.value = header.value.replace("{" + variable + "}", value); }); requestHeaders[header.name] = header.value; }); requestHeaders["x-apigee-callback"] = "true"; var myRequest = new Request(set.url, "GET", requestHeaders); // asynchronous GET for performance reasons var myResult = httpClient.send(myRequest); if (sync) { // Wait for the asynchronous GET request to finish myResult.waitForComplete(); // get the response object from the exchange var response = myResult.getResponse(); // get the HTTP status code from the response context.setVariable("preheatCache." + setName + "ResponseStatus", response.status); } } } function getVariables(str) { var ret = [], segments = str.split("{"); segments.forEach(function(segment) { theVar = segment.split("}"); if (theVar[0] && theVar.length > 1) ret.push(theVar[0]); }); return ret; }
Other clients have reused their JMeter tests as load generators and implemented a CRON job to periodically run scenarios to preheat caches.
User | Count |
---|---|
7 | |
2 | |
2 | |
1 | |
1 |