温馨提示×

如何排查Ubuntu Tomcat性能问题

小樊
50
2025-11-29 07:11:54
栏目: 智能运维

Ubuntu Tomcat性能问题排查与优化

一、快速定位流程

  • 明确症状:是响应变慢吞吐下降偶发超时/报错,还是频繁重启/宕机
  • 资源先行:用系统工具查看CPU、内存、磁盘I/O、网络是否存在瓶颈。
  • 线程与队列:确认Tomcat线程池是否打满、队列是否积压
  • JVM与GC:检查堆内存GC暂停是否异常。
  • 外部依赖:数据库、缓存、消息队列、外部API是否变慢或超时
  • 日志与访问轨迹:核对catalina.outlocalhost_access_log的时间点与错误堆栈,定位慢请求与异常来源。

二、关键指标与定位方法

  • 系统资源
    • CPU/内存/负载:top/htop、free -h、vmstat 1、iostat -x 1、sar -n DEV 1。关注load average与CPU iowait。
  • Tomcat线程与连接器
    • 线程池是否耗尽:ps -Lf | wc -l 查看线程数;对比 server.xml 中 maxThreads/acceptCount
    • 访问日志定位慢请求:tail -f /var/log/tomcat/localhost_access_log* 或 /opt/tomcat/logs/localhost_access_log,按时间过滤并分析耗时与返回码。
  • JVM与GC
    • 打开GC日志(在 catalina.sh 的 JAVA_OPTS 中增加 -Xlog:gc,gc+heap=debug:file=/opt/tomcat/logs/gc.log:time,tags*),观察Full GC频率与停顿。
    • jstat -gc 1s 观察年轻代/老年代使用与GC次数。
  • 文件句柄与连接
    • 句柄泄漏:lsof -p | wc -l;对比 ulimit -n。
    • 连接数:ss -tan | grep :8080 | wc -l;netstat -anp | grep :8080。
  • 外部依赖
    • 数据库慢查询、连接池耗尽;Redis/消息队列超时;第三方API延迟上升。

三、常见症状与处理要点

  • 线程池耗尽与排队
    • 现象:大量请求排队、响应时间飙升、catalina.out 出现线程创建受限提示。
    • 处理:在 server.xml 调整 maxThreads(如200–500视硬件而定)、acceptCount(队列长度)、minSpareThreads;或定义共享 并在 Connector 上引用,提高可维护性。
  • 连接超时与网关超时
    • 现象:前端/网关报504/超时,Tomcat日志出现connectionTimeout
    • 处理:合理设置 Connector 的 connectionTimeout(如20000 ms);若经 Nginx/Apache 反向代理,同步调大 proxy_connect_timeout / proxy_read_timeout / proxy_send_timeout(如60s)。
  • 内存不足与频繁GC
    • 现象:GC日志中Full GC频繁、应用停顿明显。
    • 处理:在 catalina.sh 设置 -Xms/-Xmx(如 -Xms2g -Xmx2g)、-XX:MaxMetaspaceSize=…,选择合适的GC(如 -XX:+UseG1GC),并分析对象生命周期与缓存使用。
  • 文件句柄耗尽
    • 现象:出现 “Too many open files”,新连接失败。
    • 处理:提升进程句柄上限(如 ulimit -n 65536),并在系统级(/etc/security/limits.conf)与 systemd 服务单元中设置;排查连接泄漏与未关闭资源。
  • 访问日志揭示慢请求
    • 现象:个别接口/资源耗时远高于均值。
    • 处理:基于 localhost_access_log 的时间戳与URL筛选慢请求,结合代码与依赖逐项优化(SQL索引、缓存、批处理、异步化)。

四、配置与优化示例

  • 连接器与线程池(server.xml)
    • 共享线程池:
      <Executor name="tomcatThreadPool"
              namePrefix="catalina-exec-"
              maxThreads="500" minSpareThreads="20" maxIdleTime="60000"/>
      <Connector executor="tomcatThreadPool"
                 port="8080" protocol="HTTP/1.1"
                 connectionTimeout="20000"
                 maxKeepAliveRequests="100"
                 acceptCount="100"
                 redirectPort="8443"/>
      
    • 反向代理超时对齐(Nginx):
      location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        send_timeout 60s;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
      }
      
  • JVM与GC(catalina.sh 的 JAVA_OPTS)
    • 建议固定堆并启用G1(示例值,按内存与负载调整):
      -Xms2g -Xmx2g
      -XX:MaxMetaspaceSize=512m
      -XX:+UseG1GC
      -Xlog:gc*,gc+heap=debug:file=/opt/tomcat/logs/gc.log:time,tags
      
  • JMX远程监控(便于用 JConsole/VisualVM 实时观测)
    • 方式一(JMX Remote):
      JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote
        -Dcom.sun.management.jmxremote.port=9090
        -Dcom.sun.management.jmxremote.authenticate=false
        -Dcom.sun.management.jmxremote.ssl=false"
      
    • 方式二(JmxRemoteLifecycleListener,需 server.xml 中 Listener 配置)。
    • 重启 Tomcat 后用 JConsole 连接 :9090 查看线程、内存、类加载、MBean 等指标。

五、持续监控与可视化

  • 日志与可视化
    • 实时查看:tail -f /var/log/tomcat/catalina.out*;按关键字过滤(如 grep -i “ERROR”)。
    • 集中化:用 ELK(Elasticsearch/Logstash/Kibana)Grafana+Prometheus 收集并展示访问日志、JVM指标与应用指标。
  • 监控工具链
    • JMX + VisualVM 做本地/远程诊断;
    • Zabbix + Java Gateway 做企业级监控告警;
    • Prometheus + Grafana 做时序可视化与容量规划。

提示

  • 任何参数调整都应基于基线数据(当前吞吐、P95/P99时延、GC停顿、CPU/内存/IO)进行,先小步变更、A/B验证,再推广到生产。
  • 若使用容器/云环境,还需核对容器配额(CPU/内存)宿主机资源,避免因限额导致性能异常。

0