Load testing creates challenges when working with dynamic DNS setups such as CDNs or your very own DNS-based load balancing.
While the resolution to a single IP address via a DNS resolution call is pretty simple, resolving IPs that are changing over time or by location might create issues for setup and execution. It also makes debugging harder. XLT offers several options to deal with these situations.
Standard DNS Resolution
Address resolution with Java is not perfect in the context of load tests which are using DNS load-balancing concepts:
- Java’s address resolution cache is global to the JVM. When an entry expires, it expires for all virtual users in this JVM at the same time. As a consequence, if the IP address has changed, all traffic generated by this JVM hops from the current server to another one almost immediately.
- Java does not perform an automatic round-robin for multiple IP addresses. Java caches the IP addresses in the order received and returns them in the same order for the lifetime of the cache entry. This way, the first IP address will typically get all the traffic.
First of all it is important to get more insights into the IPs address resolution. You can enable additional IP data logging to get details about the IP used via the result data files.
xlt.dns.recordAddresses = true
Pleases note that the IP is only logged when it has been resolved. Subsequent use by utilizing the DNS cache is not logged. This reduces the size of the data files, because IP addresses are typically valid for longer periods of time.
XLT comes with some enhancements to improve the load distribution. To tackle the first issue, XLT can maintain a separate address resolution cache for each virtual user. This cache is valid for the lifetime of a virtual user’s session (i.e. one iteration). This somewhat softens the transition to the new IP address a bit, as the current session is still using the old IP address. XLT fixes the second issue by automatically shuffling the IP addresses so all IPs will be utilized equally.
Enable these features by setting the following properties as needed:
xlt.dns.cacheAddresses = true xlt.dns.shuffleAddresses = true
- cacheAddresses: Enable caching of resolved addresses for the whole lifetime of a WebClient which is typically a transaction unless special scenarios have been implemented to simulate using a second virtual browser for instance
- shuffleAddresses: Enables a random selection of IPs from returned list instead of using the first one all the time (Java standard behavior)
Use Only One Address
In case a host name is resolved to more than one IP address, the underlying
HttpClient will try one IP after the other until a connection could be established. This process is silent. Issues are only noticed if none of the given IPs could be contacted, because only then will we see exceptions bubbling up. This might lead to hard to explain results, especially when the total request runtime and socket timings do not match.
If you suspect issues with one of the servers, but these issues are masked by the silent failover to another server, you can debug this much better by limiting the selection list. Set the following property and XLT will randomly pick a single IP address from the list of available addresses:
xlt.dns.pickOneAddressRandomly = true
If the server with the chosen IP address has issues, you will spot them immediately. And when you combine this property with
xlt.dns.recordAddresses=true, you will immediately know which IP/server instance is the offending one.
Changing Cache Time
The standard DNS handler of Java caches entries sometimes beyond the regular cache lifetime announced during resolution. To overwrite this and ask more often for a new resolution, set the cache duration. But please keep in mind that a low value might cause unwanted high traffic to your next resolver.
xlt.dns.providers.platform.cache.duration = 30
- cache.duration: the number of seconds an entry is available in Java’s global resolution cache
Please note that this value only applies to the Java resolution cache. When you set the alternative provider, this value is not used.
Using an Alternative Provider
XLT brings a second way of resolving DNS names and uses dnsjava for that. Before you change this, make sure you understand the problem you want to solve. DNS resolution by Java improves with new Java releases and hence the reason for adding dnsjava to support eDNS and allow us to overwrite the DNS servers might not longer hold true.
Especially when you have trouble resolving DNS names behind CDNs, where the CDN load balances using DNS entries, trying this alternative provider might be an option. It supports EDNS which is an extension to DNS and allows the resolver to return data based on the users location instead of its own location or subnet.
xlt.dns.provider = platform
- provider: changes the underlying DNS service provider (“platform” or “dnsjava”), platform is the default value
Additional settings permit to customize the behavior of dnsjava:
## Settings for the DnsJava-based DNS service provider. ## - resolver.servers ... the list of DNS server addresses (empty for system defaults) ## - resolver.timeout ... the DNS server timeout [s] ## - edns.version ....... the DNS extension version (-1 to disable extensions) xlt.dns.providers.dnsjava.resolver.servers = xlt.dns.providers.dnsjava.resolver.timeout = 5 xlt.dns.providers.dnsjava.edns.version = 0
The values shown are the defaults.
When you use your own networking library for communication with services, none of the properties above might kick in. The XLT-DNS properties rely on the use of the WebClient or HttpClient provided by XLT.