You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring+Tomcat8.5环境下ServletOutputStream写入PDF文件异常求助

Hey there, let's break down this problem step by step—since most users are working fine but a subset is hitting that ERR_EMPTY_RESPONSE after 3 minutes of lag, it's likely a scenario-specific issue rather than a global configuration bug. Here are the key areas to investigate:

1. Tomcat Timeout & Connection Settings

First, let's rule out Tomcat's connection and async timeouts, since the 3-minute window lines up with common timeout thresholds:

  • Check your server.xml's Connector configuration for these parameters:
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               keepAliveTimeout="60000"
               asyncTimeout="180000" />
    
    The asyncTimeout (set to 180s here) is a big one if your PDF generation uses async servlets—if the task takes longer than this, Tomcat will kill the connection, leading to an empty response.
  • Also, verify if Tomcat's connectionTimeout is set too low for large PDF generation tasks, though 20s is the default and your users are waiting 3 minutes, so this is less likely unless there's queueing.
2. PDF Generation & Database Bottlenecks

Since only some users are affected, the problem might be tied to specific data sets they're requesting:

  • Slow Database Queries: Some users might be triggering queries that pull way more data than usual. Enable your database's slow query log to catch these, then check for missing indexes, N+1 query issues in your Spring Data/JPA code, or unoptimized joins.
  • PDF Rendering Resource Limits: Generating large or complex PDFs (with lots of images, tables, or dynamic content) can hog CPU and memory.
    • Use tools like jstat or jconsole to monitor your Tomcat JVM's memory usage—frequent Full GC pauses can freeze responses until the JVM recovers.
    • Double-check your PDF library (iText, PDFBox, etc.) code: make sure you're closing all resources (like Document or InputStream instances) with try-with-resources blocks to avoid leaks.
3. ServletOutputStream Handling Mistakes

In Spring apps, improper handling of ServletOutputStream is a common culprit for empty responses:

  • Missing Response Headers: Without setting Content-Length, Tomcat uses chunked transfer encoding, which some older browsers or proxies struggle with during long downloads. Add these headers before writing to the stream:
    response.setContentType("application/pdf");
    response.setContentLengthLong(calculatedPdfSize); // Calculate this before generating if possible
    response.setHeader("Content-Disposition", "attachment; filename=\"generated-document.pdf\"");
    
  • Unclosed/Unflushed Streams: If you forget to call out.flush() or don't properly close the stream (especially in error cases), Tomcat might hold the connection open until it times out. Use try-with-resources to guarantee cleanup:
    try (ServletOutputStream out = response.getOutputStream()) {
        // Generate and write your PDF to out
        out.flush();
    } catch (Exception e) {
        // Make sure to send an error response instead of leaving the connection hanging
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to generate PDF");
    }
    
  • Async Task Misconfiguration: If you're using @Async for PDF generation, ensure you're properly wiring the task to complete and send the response—if the async task hangs or fails to notify the servlet, Tomcat will kill the connection after asyncTimeout.
4. Network/Proxy Interferences

Sometimes the issue isn't on your server, but in the user's network:

  • Ask affected users if they're behind an enterprise proxy, VPN, or firewall—these often have strict timeout rules for long-running requests.
  • Test adding these response headers to help proxies handle the download better:
    response.setHeader("Connection", "keep-alive");
    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    
5. Tomcat Thread Pool Limits

If your Tomcat thread pool is exhausted, new requests will queue up until threads become available—leading to long delays and eventual timeouts:

  • Check your server.xml's Executor configuration:
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
              maxThreads="200" minSpareThreads="25"
              queueCapacity="100"/>
    
    If maxThreads is too low or queueCapacity is filled, requests will wait indefinitely. Monitor Tomcat's thread usage via the manager app to see if this is happening.

内容的提问来源于stack exchange,提问作者DFL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:11:16