Boost SpringBoot Performance: Monitoring, Profiling, and Optimization Techniques
This guide walks through practical SpringBoot performance improvements, covering metric exposure with Prometheus, flame‑graph profiling via async‑profiler, distributed tracing with SkyWalking, HTTP and Tomcat tuning, and layer‑specific optimizations for controllers, services, and data access.
1. Monitoring First
Before optimizing a
SpringBootservice, expose its metrics. Use
Prometheusas a time‑series database and add the Actuator and Micrometer Prometheus dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>Enable the endpoints in
application.properties:
management.endpoint.metrics.enabled=true
management.endpoints.web.exposure.include=*
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=trueAfter starting, metrics are available at
http://localhost:8080/actuator/prometheus.
2. Java Flame Graphs
Use
async-profilerto generate flame graphs. Extract the archive, then run the application with the javaagent:
java -agentpath:/root/build/libasyncProfiler.so=start,svg,file=profile.svg -jar spring-petclinic-2.3.1.BUILD-SNAPSHOT.jarAfter stopping the process,
profile.svgcontains a visual hotspot analysis.
3. SkyWalking
Instrument the service with the SkyWalking JavaAgent to collect tracing data. Install the agent, then start the service with:
java -javaagent:/opt/skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=the-demo-name -jar /opt/test-service/spring-boot-demo.jar --spring.profiles.active=devOpen the SkyWalking UI to locate high‑QPS, slow‑response endpoints for targeted tuning.
4. General Optimization Ideas
A typical request passes DNS, Nginx reverse proxy, and SpringBoot’s embedded Tomcat (MVC) before reaching the database.
5. HTTP Optimizations
Use a CDN for large static assets.
Set appropriate
Cache-Controland
Expiresheaders.
Limit the number of distinct domains per page (ideally ≤4).
Enable gzip compression in Nginx.
Compress JavaScript, CSS, and HTML files.
Enable keep‑alive connections for both client‑Nginx and Nginx‑backend.
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
# cache 1 year
add_header Cache-Control: no-cache, max-age=31536000;
}
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_types text/plain application/javascript text/css;6. Tomcat Tuning
Adjust thread pool, connection limits, and timeouts via a custom
WebServerFactoryCustomizer:
@SpringBootApplication(proxyBeanMethods = false)
public class App implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
TomcatServletWebServerFactory f = (TomcatServletWebServerFactory) factory;
f.setProtocol("org.apache.coyote.http11.Http11Nio2Protocol");
f.addConnectorCustomizers(c -> {
Http11NioProtocol p = (Http11NioProtocol) c.getProtocolHandler();
p.setMaxConnections(200);
p.setMaxThreads(200);
p.setSelectorTimeout(3000);
p.setSessionTimeout(3000);
p.setConnectionTimeout(3000);
});
}
}Switching from Tomcat to Undertow reduces footprint:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>7. Layer‑Specific Optimizations
Controller Layer
Return lightweight DTOs and consider asynchronous servlets to avoid large JSON payloads that increase memory usage.
Service Layer
Keep services stateless, apply appropriate design patterns, and handle distributed transactions carefully; use flexible (BASE) transactions or compensation mechanisms when strict ACID is too costly.
DAO Layer
Leverage caching, avoid eager loading of large associations, and be mindful of sharding‑induced query overhead.
End
We reviewed common SpringBoot performance‑boosting strategies, introduced three profiling tools (Prometheus, flame graphs, SkyWalking), and outlined optimizations at HTTP, container, and code‑level layers. Applying these techniques can significantly improve latency and throughput for Java backend services.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.