This is the blog section. It has two categories: News and Releases.
Files in these directories will be listed in reverse chronological order.
This the multi-page printable view of this section. Click here to print.
This is the blog section. It has two categories: News and Releases.
Files in these directories will be listed in reverse chronological order.
Recently we’ve launched a new version of our Real Load portal which adds the ability to periodically monitor your applications. The best thing to it is that you can re-use already developed load testing scripts to periodically monitor your applications. It makes sense to re-use the same underlying technology for both tasks, correct?
And, of course, nobody forces you to have the main followed by the dessert. You can also first have the dessert (… synthetic monitoring) followed by the main (… load testing). Or perhaps the dessert is the main for you, you can arrange the menu as it best suits your taste.
As for load testing, you’ll first have to prepare your testing script. Let’s assume you’ve already prepared it using our Wizards. Once the script is ready, the only remaining thing to do is to schedule it for periodic execution.
You can setup so called Monitoring Groups which will be made up of a number of Monitoring Jobs. Each monitoring job executes one of the prepared test scripts.
In this screenshot you’ll see one Monitoring Group called “Vinnuo APIs” (in the red box) which executes one test script, highlighted in the green box.
The key properties you can configure on a Monitoring Group are:
Last, you can enable/disable execution for the group by using the Execution Enabled toggle switch.
Next, you’ll add at least one Monitoring Job to the Monitoring test. Simply select from one of your projects a Test that was previously prepared.
In this example, I’ve picked one of the test that generates the relevant REST API call(s).
Next you’ll need to configured these key parameters relating to the execution of the test script. If you’re familiar with the load testing features of our product, these parameters will be familiar:
A synthetic monitoring solution wouldn’t be complete with an alerting functionality.
You can configure Alerting Groups to which you can assign a number of different device types to be alerted. Supported device types are:
In this example, I’ve created an alerting group called “SafeArea IT”…
… to which I’ve assigned one email alerting device. Needless to say, you can assign the same alerting group to multiple
Now that the Alerting Groups are configured, you can configure alerting at the Monitoring Group or Monitoring Job level, whichever best suits your use case. Simply click on the alert icon and assign the Alerting Groups accordingly:
Once you’re done with the configuration, you’ll be able to monitor the health of your applications from the Real Time Dashboard. Please note that his dashboard is in evolution, and we’re adding new features on a regular basis.
For now, you’ll be able to:
This screenshot shows the logs collected for the last job execution (green arrow). Note the additional logfiles (higlighted in the green box) that you can look at.
Regardless of whether your looking for a Synthetic Monitoring or Perfomance Testing solution, we can satisfy both needs.
Sign up for a free account on our portal portal.realload.com and click at “Sign up” (no Credit Card required). Then reach out to us at support@realload.com so that we can get you started with your first project.
Happy monitoring and load testing!
Do you need to record HTTP requests for your test script that require SSL Cert Client authentication? Tick, we support this use case now…
The Proxy Recorder has been enhanced to support recording against websites or applications that require presenting a valid SSL Client certificate.
From an high-level point of view this is how things work:
SSL Client certificates in the .pfx/.p12 format need to be uploaded to the Real Load Portal server.
The configuration of such SSL Client certificates in the Real Load Portal server is done by going to the Remote Proxy Recorders menu item and then clicking on the certificate symbol:
Then provide details about the certificate your uploading. Importantly the target server host must exactly match the hostname (or IP address) that will appear in HTTP requests.
Done. Once uploaded, using the Proxy Recorder attempt to access a resource that requires SSL Client Cert authentication. You should be able to access the resource.
Most performance testing scenarios involve an application or an API presented over the HTTP or HTTPS protocol. The Real Load performance testing framework is capable of supporting essentially any type network application, as long as there is a way to generate valid client requests.
Real Load testing scripts are Java based applications that are executed by our platform. While our portal offers a wizard to easily create tests for the HTTP protocol, you can write write a performance test application for any network protocol by implementing such a Java based application.
This article illustrates how to prepare a simple load test application for a non-HTTP application. I’ve chosen to performance test our lab MS-SQL server. What I want to find out is how the SQL server performs if multiple threads attempt to update data stored in the same row. While the test sounds academic, this is a scenario I’ve seen leading to performance issues in real life applications…
Key requirements to implement such an application are:
Using your preferred Java development environment, create a project and add the following dependencies to it:
In NetBeans, the dependencies section would look as follows:
Once the dependencies are configured in your project, we’ll implemented the test logic (the AbstractJavaTest interface). For this application, we’ll create the below class.
Of particular relevance are these methods:
import com.dkfqs.tools.javatest.AbstractJavaTest;
import com.dkfqs.tools.javatest.AbstractJavaTestPeriodicThread;
import com.dkfqs.tools.javatest.AbstractJavaTestPeriodicThreadInterface;
import com.dkfqs.tools.logging.CombinedLogAdapter;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.pool.HikariPool;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.Instant;
import javax.sql.DataSource;
@AbstractJavaTest.ResourceFiles(fileNames = {})
public class MSSQLTest extends AbstractJavaTest implements AbstractJavaTestPeriodicThreadInterface {
private static HikariPool pool;
private static HikariDataSource dataSource = null;
/**
* Static Main: Create a new instance per simulated user and execute the
* test.
*
* @param args the command line arguments
*/
public static void main(String[] args) throws SQLException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
stdoutLog.message(LOG_INFO, "Max. Java Memory = " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " MB");
dataSource = new HikariDataSource();
dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dataSource.setJdbcUrl("jdbc:sqlserver://192.168.11.61:1433;databaseName=DEMO_DB;multiSubnetFailover=true;applicationName=RealLoad");
dataSource.setUsername("sqluser");
dataSource.setPassword("password");
dataSource.setMinimumIdle(100);
dataSource.setMaximumPoolSize(2000);
dataSource.setAutoCommit(true);
dataSource.setLoginTimeout(3);
dataSource.setConnectionTimeout(3000);
java.lang.reflect.Field field;
field = dataSource.getClass().getDeclaredField("pool");
field.setAccessible(true);
pool = (HikariPool) field.get(dataSource);
// log test specific resource files, annotated by @AbstractJavaTest.ResourceFiles at class level
logTestSpecificResourceFileNames(MSSQLTest.class);
try {
// get all generic command line arguments
abstractMain(args);
// create a new instance per simulated user
for (int x = 0; x < getArgNumberOfUsers(); x++) {
new MSSQLTest(x + 1);
}
// start the test
stdoutLog.message(LOG_INFO, "[Start of Test]");
try {
// start the user threads
startUserThreads();
// wait for the user threads end
waitUserThreadsEnd();
} catch (InterruptedException ie) {
stdoutLog.message(LOG_WARN, "Test aborted by InterruptedException");
}
stdoutLog.message(LOG_INFO, "[End of Test]");
} catch (Exception ex) {
stdoutLog.message(LOG_FATAL, "[Unexpected End of Test]", ex);
} finally {
closeOutputFiles();
}
}
/**
* Close all output files.
*/
private static void closeOutputFiles() {
}
// - - - vvv - - - instance - - - vvv - - -
private CombinedLogAdapter log = new CombinedLogAdapter();
/**
* Constructor: Create a new instance per simulated user.
*
* @param userNumber the simulated user number
* @throws IOException if the user statistics out file cannot be created
*/
public MSSQLTest(int userNumber) throws IOException {
super(userNumber);
addSimulatedUser(this);
}
@Override
public void declareStatistics() {
declareStatistic(0, STATISTIC_TYPE_SAMPLE_EVENT_TIME_CHART, "Get connection from pool", "", "Execution Time", "ms", 0, true, "");
declareStatistic(1, STATISTIC_TYPE_SAMPLE_EVENT_TIME_CHART, "Exec SQL Update stmnt ", "", "Execution Time", "ms", 1, true, "");
}
@Override
public void executeUserStart(int userNumber) throws Exception {
// start a periodic thread that reports summary measurement results measured across all simulated users
if (userNumber == 1) {
AbstractJavaTestPeriodicThread periodicThread = new AbstractJavaTestPeriodicThread(this, 1000L, this);
periodicThread.setName("periodic-thread");
periodicThread.setDaemon(true);
periodicThread.start();
}
}
@Override
public int executeUserSession(int userNumber, int sessionLoopNumber) throws Exception {
long measurementGroupStartTime$0 = System.currentTimeMillis();
registerSampleStart(0);
// 1- Get a connection from pool
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (Exception e) {
log.message(LOG_ERROR, e.getMessage());
return SESSION_STATUS_FAILED;
}
addSampleLong(0, System.currentTimeMillis() - measurementGroupStartTime$0);
// 2 - Prepare SQL statement
Statement st = connection.createStatement();
String SQL = "update TEST_TABLE set VALUE_NUM = '7058195060625506304' where DATA_URI = '2566' AND DATA_URI = '0' AND DATA_ID = '-1'";
// 3 - Execute statement
registerSampleStart(1);
long measurementGroupStartTime$1 = System.currentTimeMillis();
st.executeUpdate(SQL);
addSampleLong(1, System.currentTimeMillis() - measurementGroupStartTime$1);
st.close();
connection.close();
// end of passed session
return SESSION_STATUS_SUCCESS;
}
@Override
public void executeUserSessionEnd(int sessionStatus, int userNumber, int sessionLoopNumber) throws Exception {
}
/**
* Called periodically by an independent thread with the context of the
* first simulated user. Reports summary measurement results which were
* measured over all simulated users.
*
* @param abstractJavaTest the context of the first simulated user
* @throws Exception if an error occurs - logged to stdout
*/
@Override
public void onPeriodicInterval(AbstractJavaTest abstractJavaTest) throws Exception {
}
@Override
public void onUserSuspend(int userNumber) throws Exception {
}
@Override
public void onUserResume(int userNumber) throws Exception {
}
@Override
public void executeUserEnd(int userNumber) throws Exception {
}
@Override
public void onUserTestAbort(int userNumber) throws Exception {
}
}
Once you’ve compiled your application and generated a jar file (… make sure the main class is mentioned in the META-INF/MANIFEST.MF file) you’re ready to configure the load test in the Real Load portal.
After logging into the portal, create a new project (… “MSSQL” in the below screenshot) and a new Resource Set (“Test 1”). Upload your performance test application jar file (“RealLoadTest3.jar” in this example) and all other dependencies.
Once everything is uploaded, define a new test by clicking on the Resource Set (“Test 1”). Make sure you select the .jar file you’ve developed as the “Executing Script” and tick all the required dependencies in the Resource list.
You’re now ready to execute your performance test. When starting the test job select how many threads (Users) should execute you test application, ramp up time and test execution duration.
While the performance test is executing, you’ll notice that the metrics you’ve declared in the Java source code appear in the real time monitoring window:
If you keep an eye on MS-SQL Management Studio, in the activity monitor you’ll notice that resource locking is the wait class with the highest wait times. Not so surprisingly I might add, given the nature of the test.
Also note that the waiting task number is very close to the number of virtual users (concurrent threads) simulated, approx. 100.
Once the test completed, you can review collected metrics. The graph at the bottom of this screenshot shows execution times throughout the test of the SQL update statement, as load ramped up.
As you can see, it’s quite straightforward to prepare an application to performance test almost any network protocol.
Should you have a requirement to performance test an exotic protocol and your current tool doesn’t allow you to do so, do not hesitate to contact us. Perhaps we can help…
Thank you for reading and do not hesitate to reach out should you have any Qs.
An exciting new feature was added in Real Load v4.7.3. The URL Explorer feature allows you to quickly handle session specific random values that might appear in your load test script requests and responses.
In a nutshell, this is how things work:
All of this is documented in this short video (7 minutes) which walks you through the above process.
As always, feedback or questions are welcome using our contact form.
While running a load test against an API product that I have to deal with in my other day to day job, I’ve noticed something in both the results and at the OS level (… on the DB server) that didn’t make much sense.
The results of the performance test where somewhat OK but kinda unstable (… some strange variances in the response times). This graph tells the story better than 1000s of words.
Note the green line (transactions per second) going all over the place:
At first I suspected some sort of issue with the application server (Weblogic) and the DB Connection Pool. But all looked good there…
Then I’ve cast an eye on Oracle Enterprise Manager and noticed that most of the DB waits were related to I/O, although the storage of this particular test DB is located on a reasonably fast NVME SSD.
So I started looking at I/O stats on the Oracle Linux server hosting this DB. Being a lab DB, it’s more or less a standard Oracle install with not much performance tuning applied. Nor am I an Oracle expert that knows all secrets of the trade…
Anyways, there was one thing that somehow didn’t stack up: At the OS level, the % spent by the CPU in iowait was sporadically incredibly high (… 70%+ or so) with the CPU idle time plunging to less than 10%:
After reading various online articles about this, most of which suggested beefier HW or rewrite the app the app so that it would be more efficient with commits, it dawned on my that perhaps Oracle wasn’t using async I/O when writing to disk causing these high waitio stats.
I finally bumped into a few articles talking about async I/O settings in Oracle and found a few useful SQL queries…
This one will assist in figuring out whether async I/O is enabled on your Oracle DB files:
COL NAME FORMAT A50
SELECT NAME,ASYNCH_IO FROM V$DATAFILE F,V$IOSTAT_FILE I
WHERE F.FILE#=I.FILE_NO
AND FILETYPE_NAME='Data File';
… leading to a result like this. Note that for all files async IO is disabled…
So I decided to enable async I/O with these few SQL commands:
ALTER SYSTEM SET FILESYSTEMIO_OPTIONS=SETALL SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
… and then checking again. As you can see, async I/O is enabled now:
NAME ASYNCH_IO
-------------------------------------------------- ---------
/opt/oracle/oradata/AAOP74/datafile/o1_mf_system_j ASYNC_ON
zml41fy_.dbf
/opt/oracle/oradata/AAOP74/itblspc01.dbf ASYNC_ON
/opt/oracle/oradata/AAOP74/datafile/o1_mf_sysaux_j ASYNC_ON
zml5rwh_.dbf
/opt/oracle/oradata/AAOP74/datafile/o1_mf_undotbs1 ASYNC_ON
_jzml6l1k_.dbf
/opt/oracle/oradata/AAOP74/dtblspc01.dbf ASYNC_ON
NAME ASYNCH_IO
-------------------------------------------------- ---------
/opt/oracle/oradata/AAOP74/datafile/o1_mf_users_jz ASYNC_ON
ml6m5f_.dbf
/opt/oracle/oradata/AAOP74/btblspc.dbf ASYNC_ON
/opt/oracle/oradata/AAOP74/cm.dbf ASYNC_ON
/opt/oracle/oradata/AAOP74/cm.idx ASYNC_ON
/opt/oracle/oradata/AAOP74/bodtblspc.dbf ASYNC_ON
/opt/oracle/oradata/AAOP74/boitblspc.dbf ASYNC_ON
/opt/oracle/oradata/AAOP74/DTBLSPC03.dbf ASYNC_ON
/opt/oracle/oradata/AAOP74/ITBLSPC03.idx ASYNC_ON
/opt/oracle/product/19c/dbhome_1/dbs/reportdt.dat ASYNC_ON
14 rows selected.
Time to re-run the load test with my preferred tool and the results look encouraging.
As you can see the green results line is much more stable. Not only that, but number of transactions per second (TPS) increased to approx. 136 from 101 in the previous run. Response times also went down somewhat, from 90 to 70ish msecs.
The CPU waitio stats also dramatically improved on the Oracle server:
To summarize, it makes sense to scratch beyond the surface of performance bottlenecks before investing in HW upgrades or so… Sometimes the solution is a low-hanging fruit waiting to be picked.
For various reasons, I’ve had to perform a series of tests to ensure our Measuring Agent can generate traffic from a large number of source IP addresses. Aside from validating that capability, the by-result of the test is a somewhat interesting comparison of a FreeBSD and Linux based Apache HTTPD server.
First, a quick overview of what I wanted to prove: I needed to make sure that we can run a Load Test simulating a large number of source IP addresses. To validate this requirement, I’ve configured one of our Measuring Agents with approx. 12k IP addresses. I’ve used a bash script to do that, as otherwise it would take forever. All IPs are assigned as aliases to the NIC from where the load will be generated, and all IPs are within the same /16 subnet.
Finally, I’ve configured my Real Load test script with two additional steps:
The hypervisor is a Windows 2019 Server Standard edition machine, running Hyper-V and fitted with an somewhat old Xeon E5-2683v3 CPU. The measuring agent and the tested servers are connected to the same virtual switch.
The Linux and FreeBSD VMs are minimal instals of their distributions, onto which I’ve installed the latest Apache HTTPD build offered by the built in software distribution mechanisms. That’s why the HTTPD versions are not identical.
In order for the results to be somewhat comparable, I’ve deployed the same set of static HTML pages on both servers. I’ve also aligned several key HTTPD config parameters on both systems, as shown in this table.
Parameter | Measuring Agent | FreeBSD HTTPD VM | Linux HTTPD VM |
---|---|---|---|
OS Version | RH 8.4 | 13.0 | Oracle Lnx 8.4 |
RAM | 4 GBs | 4 GBs | 4 GBs |
vCPUs | 10 | 4 | 4 |
HTTPD Version | n/a | 2.4.53 | 2.4.37 |
HTTPD MPM | n/a | event | event |
ServerLimit | n/a | 8192 | 8192 |
MaxRequestWorkers | n/a | 2048 | 2048 |
ThreadsPerChild | n/a | 25 | 25 |
See further down for other tuning parameters applied to the HTTPD VMs.
I’ve then executed a 20 minutes 1000 VUs load test which, which is configured to maximize the number of HTTP requests generated. Apache is configured to server some static HTML pages, made up of text and some images.
This table summarizes metrics observed once the max. load was reached, approx. 10 minutes into the test. The PDF reports allow you to have a better glance into the test results.
Metric | Linux HTTPD | FreeBSD HTTPD |
---|---|---|
User CPU usage | 21% | 20% |
System CPU usage | 47 % | 70% |
Avg reqs/s | 8.8k | 10.3k |
Avg network throughput | 1.1 Gbps | 1.3 Gbps |
Hyper-V CPU usage | 10% | 11% |
Test report PDF | Linux Report PDF | FreeBSD Report PDF |
Test progress screenshot | ![]() |
![]() |
… is difficult to pick, to be honest.
Assuming I had time to spend to better tune and align the two platforms, I might have been able to squeeze out a bit more performance from each server, but I doubt that would have materially changed the result in favor of one OS or the other. Obviously I’m happy to be proven wrong…
Feel free to email us with your feedback, I’ll be more than happy to test any further tuning suggestions.
Below the OS level tuning that was applied to the Linux and FreeBSD servers. I didn’t have time to research in full each of the parameters mentioned below, they were mentioned in various other online sources and adopted. I’ve implemented the ones that seemed to make most sense…
The last 2 tunables were required to prevent the Linux server stopping accepting connections for various reasons…
fs.file-max = 524288
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 3
net.ipv4.tcp_max_orphans = 65536
net.ipv4.tcp_fin_timeout = 30
net.ipv4.ip_local_port_range = 16384 60999
net.core.somaxconn = 256
net.core.rmem_max = 1048576
net.core.wmem_max = 1048576
net.core.message_cost=0
net.ipv4.neigh.default.gc_thresh3=64000
kern.threads.max_threads_per_proc=4096
kern.ipc.somaxconn=4096
kern.ipc.maxsockets=204800
kern.ipc.nmbclusters=262144
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.maxvnodes=200000
net.inet.tcp.delayed_ack=0
net.inet.tcp.msl=5000
net.inet.tcp.maxtcptw=200000
net.inet.ip.intr_queue_maxlen=4096
net.inet.ip.dummynet.io_fast=1
The Real Load Portal portal.realload.com is open for publich registration.
Feel free to register for an account and trial our product by following the registration instructions here. You’ll be given a two weeks 100 VUs demo license and no credit card is required to sign up!
If you’d like a one-on-one session to guide you through the first steps of how to use our product, please do no hesitate to contact us at sales@realload.com .
Happy testing!
The Desktop Companion is a Desktop GUI that allows you to manage several Real Load aspects directly from your desktop.
We’ve released the latest update and this 5 minutes video illustrates the key changes.
Happy watching!
Today I’ve started executing a lengthy performance test against a SOAP API to seed the underlying DB. For various reasons, I need to replicate the daily DB volume increase of a production system in my own lab DB.
I’ve prepared a Real Load test script and started hammering a server in my lab environment. I’ve noticed the performance wasn’t particularly good but that didn’t matter, as I wasn’t actually executing a performance test.
I’ve let the test run and went for lunch (… a sandwich). When I came back, I’ve noticed that my system became somehow much faster, raising from approx. 50 TPS to approx. 200 TPS. Each transaction represents a SOAP request…
See this graph from the real time monitoring window:
Knowing how this particular product works and knowing that typically the performance is limited by the performance of the underlying DB, I’ve started looking at various DB counters and one thing I’ve noticed is that the Response Time reported by MS SQL Studio on a particular DB file went down considerably (… from 100ms+ to 10-20ms).
That was curios…. why would this happen? I’ve then cast an eye on the metrics of my storage system (a TrueNAS self build…) and noticed that the ZFS L2 ARC read cache hits improved noticeably around that time. Notice the orange line, next to 0% hit ratio around 12PM and then raising to 90%+ after approx. 50 minutes.
Anyways… this just goes to show that having access to metrics of all infrastructure components during a load test is critical. But sometimes getting to these metrics can really be hard. Just need to persist to get to be bottom of things…..
This is a short update video to illustrate enhancements in the last update of the Desktop Companion.
Enhancements were done to the Proxy Recorder tab:
All of the above is illustrated in this short video…
The Desktop Companion is a Desktop GUI that allows you to manage several Real Load aspects directly from your desktop.
It was freshly released in the last few days, plz do not hesitate to try it out. We’ve put together a short video that shows how to:
All of this in 8 minutes…
It’s the first video I’ve ever had to publish, so I apologize in advance for the rather basic editing…
A great new feature of the Real Load portal is that is allows you to share or simply consume plugins that have been prepared by others.
Plugins are written in Java. There are 3 types of plugin that are supported by the Real Load application:
One of the key fetures of the product is that plugins can be optionally be published on the Real Load portal, for other users to consume. You can have a glimpse of available plugins here.
Interested in plugins but don’t know where to start? We’ll soon publish a getting started documentation on our website. In the meantime please reach out to us at support@realload.com
The demo portal demo2.realload.com is now available for selected customers who wish to evaluate the product functionality. You need an invitation code from us to sign up at the portal.
Quick Start Guide
Note: The Measuring Agent agent2.realload.com has the following restrictions: