Tomcat 8线程引发CPU使用率过高问题排查咨询
Hey there, let's break down why your Tomcat 8 server is spiking CPU with threads tied to Tomcat's own classes, and walk through actionable steps to troubleshoot it:
Common Culprits for Tomcat Threads Driving High CPU
Before diving into fixes, let's cover the most likely causes tied to Tomcat's core components:
- Connector thread pool misconfiguration: Using the old BIO connector (each request blocks a thread) or having mismatched
maxThreads/maxConnectionsvalues that force excessive thread context switching. - SSL handshake overhead: If you're running HTTPS, frequent new connections trigger CPU-heavy SSL handshakes—especially if session reuse isn't enabled or you're using inefficient cipher suites.
- Synchronous logging bottlenecks: Tomcat's default JULI logging can cause lock contention under high load if you're using unconfigured synchronous handlers (like basic Console/File handlers).
- Session management overhead: Persisting sessions to disk/database or having excessive session creation/serialization can eat up CPU cycles.
- Lock contention in core components: Threads blocked waiting for locks in class loaders, request processing pipelines, or session managers can lead to wasted CPU cycles (even if threads show as
BLOCKEDin dumps).
Step-by-Step Troubleshooting Tips
Let's go through practical steps to pinpoint and fix the issue:
1. Drill Into Your Thread Dump Details
First, get precise with your thread analysis:
- Use
top -Hon your server to find the PID of the CPU-heavy threads, convert the PID to hexadecimal, then cross-reference it with yourjstackoutput to find the exact stack trace. - Check the thread state:
- If threads are RUNNABLE: They're actively executing code—look for loops in
org.apache.coyote.http11.Http11Processor(stuck request processing) or SSL-related classes (likeJSSESocketFactory). - If threads are BLOCKED: Identify the lock they're waiting for (e.g., a log handler lock or class loader lock) to spot contention points.
- If threads are RUNNABLE: They're actively executing code—look for loops in
2. Audit Your Connector Configuration
Tomcat's connector is often the root cause:
- Switch to the NIO or APR connector (BIO is deprecated and inefficient for high load). Update your
server.xmlto use<Connector protocol="org.apache.coyote.http11.Http11NioProtocol">or APR if you have the native library installed. - Tune thread pool settings:
- Avoid setting
maxThreadstoo high (over 200-300 for most workloads)—excess threads cause costly context switching. - Match
maxConnectionsto your server's capacity (for NIO, this is the number of concurrent connections Tomcat can handle before queuing). - Adjust
connectionTimeoutandkeepAliveTimeoutto prevent idle threads from hogging resources or forcing too many new connections.
- Avoid setting
3. Optimize SSL Settings (If Using HTTPS)
SSL is CPU-intensive—tweak these to reduce overhead:
- Ensure SSL session reuse is enabled (Tomcat defaults to this, but verify with
sslSessionTimeoutandsslSessionCacheSizein your connector config). - Use modern, efficient cipher suites (e.g., AES-GCM) and disable outdated ones like 3DES or RC4. Stick to TLS 1.2 or 1.3 to avoid legacy overhead.
4. Fix Logging Bottlenecks
Logging lock contention is a hidden CPU drain:
- Switch to asynchronous logging for JULI: Configure
AsyncHandlerWrapperinlogging.propertiesto offload log writes from request threads. - Or replace JULI with a more efficient framework like SLF4J + Logback, which handles high-concurrency logging better out of the box.
- Lower log levels from DEBUG/TRACE to INFO/WARN—verbose logging creates massive string processing and IO overhead.
5. Tune Session Management
If sessions are the issue:
- Disable session persistence (unless you need it) by setting
persistent="false"in yourContextconfig. - Reduce session timeout (e.g., from 30 minutes to 10) to clean up idle sessions faster.
- Check if your app is making excessive
getAttribute()/setAttribute()calls on sessions—each call triggers internal Tomcat processing.
6. Check for Class Loader Contention
Frequent app redeploys or multiple web apps can cause lock fights:
- Disable auto-deployment (set
autoDeploy="false"inserver.xml) if you're not using hot reloading—this prevents constant class loader reinitialization. - Avoid packaging duplicate libraries in your WAR files (e.g., servlet API jars) that conflict with Tomcat's own libraries, causing extra class loading work.
7. Monitor JVM and Server Metrics
Use tools to get a full picture:
- Run
jstat -gc <pid> 1000to check for frequent garbage collection—GC pauses can spike CPU if your heap is undersized or there's a memory leak. - Use Tomcat's built-in Manager app to track thread pool usage, request queue length, and session counts in real time.
- Use
vmstatoriostatto rule out IO bottlenecks (though high CPU usually points to CPU-intensive work, not waiting on IO).
内容的提问来源于stack exchange,提问作者sfgroups
相关产品推荐
相关产品推荐

