Troubleshooting Spring Boot CPU Spikes

Spring Boot is a widely used framework for building highly transactional Java-based web applications and backend systems. These applications process heavy loads and often have processing requirements. In this post let’s discuss how to diagnose CPU spike problems that surfaces in the Spring Boot applications.

What  is CPU Spike?

A CPU spike is a very common symptom of a Spring Boot application. Here are some common scenarios of CPU spikes are:

  • Intensive Computation: Heavy computational tasks or algorithms that require a substantial amount of processing power can lead to CPU spikes. Ensure that your algorithms are optimised and consider distributing workloads across multiple threads or processes if applicable.
  • Inefficient Code: Inefficient or poorly optimised code can result in increased CPU usage. Profiling tools can help identify hotspots in the code where optimizations are needed.
  • Memory Issues: If the application experiences memory-related problems, such as excessive garbage collection or memory leaks, it can lead to increased CPU usage. Monitoring memory usage and using profiling tools can help identify and address these issues.
  • Thread Contentions: Contentions for locks or resources among threads can cause increased CPU usage. Analyse your application for potential thread contention issues and use synchronisation mechanisms judiciously.
  • Infinite Loops or Busy-Waiting: Infinite loops or busy-waiting (repeatedly checking a condition in a loop without yielding CPU) can lead to CPU spikes. Review your code for such patterns and ensure there are proper mechanisms to prevent unnecessary CPU usage.

Simulating CPU Spike in Spring Boot

In order to simulate the CPU spike issue in Spring Boot, we leveraged the open source BuggyAPI application, a comprehensive Spring Boot service capable of simulating various performance problems. When we launched the Buggy API application, it looked as below:

Spring Boot Buggy API Service
Fig 1: Spring Boot Buggy API Service

Below is the source code of Spring Boot Buggy API service that simulates CPU Spike problem:

@Service
public class CPUSpikeDemoService {

public void start() {

new CPUSpikerThread().start();
new CPUSpikerThread().start();
new CPUSpikerThread().start();
}
}

public class CPUSpikerThread extends Thread {

private static final Logger log = LoggerFactory.getLogger(CPUSpikerThread.class);


@Override
public void run() {
log.info("Starting CPU Spike");
try {
Object1.execute();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class Object1 {

private static final Logger log = LoggerFactory.getLogger(Object1.class);

public static void execute() throws InterruptedException {
while (true) {
doSomething();
}
}

public static void doSomething() {
log.info("CPU Spike : Access console contineously");
}
}

In the above Java program, you will notice the ‘CPUSpikeDemoService’ class. In this class, 6 threads with the name ‘CPUSpikerThread’ are launched. If you notice the ‘CPUSpikerThread’ class code, there is a ‘while (true)’ loop without any code in it. This condition will cause the thread to go on an infinite loop. Since 3 threads are executing this code, all the 3 threads will go on an infinite loop. When this program is executed, CPU consumption will skyrocket on the machine.

Troubleshooting Spring Boot CPU Spikes using yCrash

In order to troubleshoot this problem, we leveraged the yCrash monitoring tool. This tool is capable of predicting outages before it surfaces in the production environment. Once it predicts outage in the environment, it captures 360° troubleshooting artifacts from your environment, analyses them and instantly generates a root cause analysis report. Artifacts it captures include Garbage Collection log, Thread Dump, Heap Substitute, netstat, vmstat, iostat, top, top -H, dmesg, kernel parameters, disk usage… You can register here and start using the free-tier of this tool.

Below is the report generated by the yCrash tool when the above sample Spring Boot program is executed:

yCrash RCS summary showing fatal errors for high CPU consumption
Fig 2: yCrash RCS summary showing fatal errors for high CPU consumption

yCrash tool point out lines of code causing the CPU spike
Fig 3: yCrash tool point out lines of code causing the CPU spike

From the report, you can observe that yCrash is pointing out the threads that are causing the CPU to spike up. In the ‘CPU | Memory’ section of this report, you can notice that CPU consumption of each thread (which is > 30%) is reported. You can also notice that tool is pointing out exact lines of code i.e., com.ycrash.springboot.buggy.app.service.cpuspike.Object1.execute(Object1.java:16) that is causing the infinite loop. Equipped with this information one can easily go ahead and fix the problematic code.

Possible Solutions

To prevent CPU spike issues, an appropriate solution needs to be applied based on the specific CPU spike problem. Here are some recommendations:

RecommendationDescription
Code OptimizationReview and optimise your code for performance. Look for areas where you can reduce unnecessary computations, loops, or resource-intensive operations.
Algorithmic OptimizationReview your algorithms and data structures. Inefficient algorithms can contribute to high CPU usage. Optimise critical sections of your code for better performance.
External ServicesCheck interactions with external services (e.g., network calls). If external services are slow or experience issues, it can impact your application’s performance. Consider implementing timeouts and retries.
Concurrency IssuesWhen dealing with thread creation and management, consider using thread pools provided by the Java Executor framework.

Conclusion

In this blog, we looked in detail at troubleshooting CPU spikes with an emphasis on detecting the root cause and resolving the CPU spike in Spring Boot applications.

Share your Thoughts!

Up ↑

Index

Discover more from yCrash

Subscribe now to keep reading and get access to the full archive.

Continue reading