-
Notifications
You must be signed in to change notification settings - Fork 0
Case 3.3
The Case. In fact, this is one of the most popular cases: select the CDN with the best performance for user's country. It is very useful and not complicated at all.
First goes our configuration
:
const configuration = {
/** List of providers configuration*/
providers: [
{
name: ('akamai' as TCDNProvider), // CDN Provider alias to work with
cname: 'my-akamai.origin.cdn.com' // cname to pick as a result
},
{
name: ('cloudflare' as TCDNProvider),
cname: 'my-cloudflare.origin.cdn.com' // cname to pick as a result
},
{
name: ('aws-cloudfront' as TCDNProvider),
cname: 'my-cloudfront.origin.cdn.com' // cname to pick as a result
},
{
name: ('verizon-edgecast-cdn' as TCDNProvider),
cname: 'my-edgecast.origin.cdn.com' // cname to pick as a result
},
{
name: ('g-core-labs' as TCDNProvider),
cname: 'my-gcore.origin.cdn.com' // cname to pick as a result
}
],
defaultTtl: 10 // The DNS TTL to be applied to DNS responses in seconds.
};
We simply list our providers candidates, their TCDNProvider-type names and the desired answers.
Then, we define our functions, we need those to determine the lowest array index and the lowest property (it will be performance
, remember, The lower value - the better performance.)
/**
* Returns index of lowest number in array
*/
const getLowest = (array: number[]): number => array.indexOf(Math.min(...array));
/**
* Picks item with lowest value in property
*/
const getLowestByProperty = <T>(array: T[], property):T => array[getLowest(array.map(item => item[property]))];
Now, the main
part, our onRequest
block.
Let's parse the configuration, try to figure out user country with PerfOps lookupCountry function, and if it is set - get ISO code of that country. Notice, that in some cases country can not be determined, so let's also declare new country
variable that will either contain ISO code or be null
.
function onRequest(req: IRequest, res: IResponse) {
const { providers, defaultTtl } = configuration;
let countryInfo = lookupCountry(req.ip);
let country: TCountry | null = null;
if (countryInfo) {
country = countryInfo.isoCode;
}
Now, let's get the array of objects with our providers and their performance. If country is not null - we will get CDN RUM performance per provider for that country, otherwise we use the world RUM performance. In both cases we use fetchCdnRumPerformance function that can take either one argument for the world performance, or three arguments for a particular location performance.
// get Providers performances
const perfProvidersData = providers.map(
(provider) => ({
provider,
perf: country &&
fetchCdnRumPerformance(provider.name, 'country', country) ||
fetchCdnRumPerformance(provider.name)
})
);
And the last touch: we get the cname
for the best-performance-provider and set it as our answer
. That's it!
const {provider} = getLowestByProperty(perfProvidersData, 'perf');
res.setCNAMERecord(provider.cname);
res.setTTL(defaultTtl);
return;
The whole script looks like:
const configuration = {
/** List of providers configuration*/
providers: [
{
name: ('akamai' as TCDNProvider), // CDN Provider alias to work with
cname: 'my-akamai.origin.cdn.com' // cname to pick as a result
},
{
name: ('cloudflare' as TCDNProvider),
cname: 'my-cloudflare.origin.cdn.com' // cname to pick as a result
},
{
name: ('aws-cloudfront' as TCDNProvider),
cname: 'my-cloudfront.origin.cdn.com' // cname to pick as a result
},
{
name: ('verizon-edgecast-cdn' as TCDNProvider),
cname: 'my-edgecast.origin.cdn.com' // cname to pick as a result
},
{
name: ('g-core-labs' as TCDNProvider),
cname: 'my-gcore.origin.cdn.com' // cname to pick as a result
}
],
defaultTtl: 10 // The DNS TTL to be applied to DNS responses in seconds.
};
/**
* Returns index of lowest number in array
*/
const getLowest = (array: number[]): number => array.indexOf(Math.min(...array));
/**
* Picks item with lowest value in property
*/
const getLowestByProperty = <T>(array: T[], property):T => array[getLowest(array.map(item => item[property]))];
function onRequest(req: IRequest, res: IResponse) {
const { providers, defaultTtl } = configuration;
let countryInfo = lookupCountry(req.ip);
let country: TCountry | null = null;
if (countryInfo) {
country = countryInfo.isoCode;
}
// get Providers performances
const perfProvidersData = providers.map(
(provider) => ({
provider,
perf: country &&
fetchCdnRumPerformance(provider.name, 'country', country) ||
fetchCdnRumPerformance(provider.name)
})
);
const {provider} = getLowestByProperty(perfProvidersData, 'perf');
res.setCNAMERecord(provider.cname);
res.setTTL(defaultTtl);
return;
}
Create your first FlexBalancer
- Case 1.1: Provider Availability with Weights.
- Case 1.2: Availability based on Monitor Uptime.
- Case 2.1: Balancing based on the CDN with the better Performance.
- Case 3.1: Geolocation with excluded country.
- Case 3.2: The specific answer for the specific region.
- Case 3.3: The provider with the best performance for visitor's country.
- Case 4.1: Using country-based answers from remote sources.