This is part 5 of our 5-part series on improving the performance of the Spring-petclinic application. Here are part 1, part 2, part 3 and part 4.
To increase application performance, one of the classic solutions is to add more cache. We already have a cache configured in the application, it is on the JpaVetRepositoryImpl.
We are going to generalize this cache on 2 different parts of the application:
You can see those changes in the following commit:
Our final result goes up to 1225 req/sec. That’s only a 15% performance boost, but please note that we have a very small database, and that it is running locally. On a real-world system, the improvement should be better, especially for the JpaOwnerRepositoryImpl.findByLastName() method.
We decided to do an extreme testing session, in order to see if we really stabilized the application (using Tomcat’s NIO connector and going stateless, specifically).
So we ran our test again on the Macbook, still with 500 threads, but this time we let it run until we had 100 000 user sessions.
Our results are extremely good:
This is, of course, an excellent result.
During those five days, we have gone through the classical steps we use at Ippon Technologies when auditing a project:
For each of these steps, JMeter and YourKit were our best tools to stress test the application and monitor how it responded to the test.
Of course, more work could have been done on JVM tuning, and on database tuning (but changing the database schema is outside the scope of this article).
At the beginning of the tests, we had to increase our heap memory size to 1 Gb, and could only serve 548 req/sec, with some HTTP errors. After completing our audit, we are now back to 128 M, and can serve 1225 req/sec with no error at all. We expect those results to be even better on a real server, with many cores and threads, and where removing JVM locks will have a more significant impact.
We also had a great improvement in the application stability, having 0 errors and 1565 req/sec with 100 000 users on our “extreme tests”. The application is now ready to handle a lot of users without any trouble.
Last but not least, we have switched the persistence layer from JDBC to JPA: a quick look at the code shows how much clearer and smaller the JPA code is. And the Spring Data JPA code is even clearer and smaller. It’s great to see that quality code can also be more performant than low-level, hard-to-code classes.
[edit]
You can find the other episodes of this series here : part 1, part 2, part 3 and part 4.