JSP 在 Ubuntu 上怎么调试?从日志、JVM 工具到远程断点的实用方法

沈亦白
沈亦白
发布时间:2026-08-22 | 197人浏览过
原创

前言

JSP 部署到 Ubuntu 后,一旦出现 500 报错、页面卡住或线上环境难以复现的问题,很多人第一反应是直接进 IDE 下断点,但这往往不是效率最高的入口。更实用的做法,是先用日志判断故障类型,再根据现象选择命令行工具、错误页配置、图形化调试或远程连接方案,逐步把范围缩小到具体代码或 JVM 指标。

JSP 在 Ubuntu 上出问题时,最常见的难点不是“不会调试”,而是不知道该先看哪里:是语法报错、线程阻塞、内存压力,还是远程环境配置有问题。下面这篇内容按排查顺序重组了一遍,从日志入口、命令行工具到 IDE 和远程调试逐步展开,方便你根据现象快速选择合适的方法。

先从日志入手,确认问题落点

排查 JSP 运行错误,第一步通常不是直接下断点,而是先看日志。Ubuntu 系统层面的日志一般位于 /var/log/syslog 或 /var/log/messages;如果应用跑在 Tomcat 上,更重要的是查看 Tomcat 自身日志目录,例如 /var/log/tomcat9/,或者对应版本下的 logs 目录。

其中,catalina.out 往往是最先要看的文件。JSP 编译失败、运行时报错、类找不到、异常堆栈等信息,通常都会先出现在这里。对于大多数“页面打不开”或“请求直接报 500”这类问题,先确认 catalina.out 中的报错类型,往往就能判断后续该走语法排查、配置修复还是 JVM 分析路线。

命令行工具怎么配合使用

如果日志只能告诉你“出错了”,但还不足以定位根因,就可以进一步借助命令行工具缩小范围。

用 System.out.println() 快速看变量和流程

这是最直接、也最容易马上见效的方法。在可疑位置加入输出语句:

System.out.println("变量值:"+variable);

然后实时查看 Tomcat 日志:

tail -f /var/log/tomcat9/catalina.out

这种方式虽然朴素,但对判断变量值是否异常、流程是否进入某个分支非常有效,特别适合处理 JSP 页面中的简单逻辑问题。

用 jstack 排查线程阻塞和死锁

当页面响应很慢、请求卡住或者怀疑线程死锁时,可以用 jstack 查看线程堆栈。先找到 Tomcat 进程 ID:

ps -ef | grep tomcat

然后执行:

jstack -l <Tomcat进程ID>

输出结果里可以重点关注 RUNNABLE 状态的线程,以及是否存在多个线程互相等待资源的情况。

用 jmap 和 jstat 观察内存与 GC 压力

如果问题表现为 Tomcat 越跑越慢、频繁 Full GC 或怀疑内存泄漏,可以先看堆内存和 GC 指标。

查看堆内存分布:

jmap -heap <Tomcat进程ID>

它会显示 Eden、Survivor、Old Gen 等区域的使用占比,适合初步判断内存压力是否集中在老年代。

持续观察 GC 指标:

jstat -gcutil <Tomcat进程ID> 1000

这里的 1000 表示每秒刷新一次。排查时通常可以重点看 O(Old 区使用率)、YGC(Young GC 次数)等指标,判断 JVM 是否处于高压状态。

把错误信息放大:日志与错误页配置

当现有日志信息还不够用时,可以通过 JVM 和 JSP 配置,把更多细节主动暴露出来。

JVM 与 JSP 调试工具对照图,说明 jstack、jmap、jstat 和 GC 日志分别用于哪些问题
调试工具与问题类型对照线程、内存、GC 和错误页配置分别解决不同类型的问题,避免工具使用方向跑偏。

启用 GC 日志

在 Tomcat 的 bin/catalina.sh 中加入 JVM 参数:

JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/var/log/tomcat9/gc.log"

重启 Tomcat 后,会生成 gc.log 文件。这个日志适合用来分析垃圾回收频率、停顿情况,以及是否需要进一步调整内存参数。

配置 JSP 错误页输出完整异常

如果你希望 JSP 出错时直接拿到更完整的异常上下文,可以在页面顶部添加:

<%@ page isErrorPage="true" %>

再将错误跳转到专门的错误页,例如 error.jsp,并通过:

exception.printStackTrace()

输出详细堆栈。对于语法错误、空指针、业务逻辑异常,这种方式比只看浏览器里的报错页更直观。

打开 JSP 调试标记

另一个常见做法,是在 JSP 页面顶部加入:

<%@ page debug="true" %>

这样在 JSP 引擎处理页面报错时,服务器通常会输出更详细的信息,比如编译错误所在的具体行号和原因。这一招对定位 JSP 语法问题尤其省时间。

IDE 图形化调试适合处理什么问题

当问题已经不是“有没有报错”,而是“代码到底走到了哪一步”,IDE 的图形化调试就比纯日志更高效。Eclipse 和 IntelliJ IDEA 都能直接配合 Tomcat 做 JSP 调试。

常见做法包括:

  • 在 JSP 的脚本段 <% ... %> 或表达式 <%= ... %> 中设置断点;
  • 通过 IDE 的 Debug 菜单启动 Tomcat;
  • 访问 JSP 页面后,在断点处暂停执行;
  • 在调试窗口查看当前作用域中的变量值、对象属性和调用栈;
  • 使用 Step Over、Step Into、Resume 等操作逐步验证执行路径。

这类方式特别适合排查条件分支判断错误、对象属性异常、方法链调用结果不符合预期等问题。

需要长期排查时,用日志框架替代临时输出

如果调试需求不只是一次性排错,而是希望后续也能稳定追踪 JSP 或相关后端逻辑,单靠 System.out.println() 就不够了。这时更适合接入日志框架,例如文中提到的 Log4j2。

添加依赖

如果项目使用 Maven,可以在 pom.xml 中加入 log4j-api 和 log4j-core 依赖,版本保持为 2.x.x。

配置输出级别与目标

在 src/main/resources 下创建 log4j2.xml,设置日志级别,例如 DEBUG,并定义输出格式与输出位置。常见配置会包含时间、线程、类名,以及输出到控制台或文件。

在代码中记录关键过程

通过 LogManager.getLogger() 获取 Logger 实例后,可以用下面的方式记录调试信息和异常:

logger.debug("调试信息")
logger.error("错误信息:"+e.getMessage())

日志可以输出到指定文件,例如 jsp-logs.log。相比临时打印,这种方式更适合保留现场、区分级别,也方便线上问题回溯。

远程服务器上的 JSP 怎么调试

如果问题只会在远程 Ubuntu 服务器上出现,本地复现不了,就需要用远程调试把 IDE 接到服务器上的 Tomcat。

远程调试连接关系图,展示 Ubuntu 服务器上的 Tomcat、5005 端口与本地 IDE 的连接方式
JSP 远程调试连接图当问题只在远程 Ubuntu 服务器上出现时,远程调试是把断点能力带到线上环境的关键手段。

先为 Tomcat 开启远程调试端口

在 catalina.sh 中加入 JVM 参数:

JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"

重启 Tomcat 后,调试端口 5005 会被打开。

再由本地 IDE 发起连接

接着在 IntelliJ IDEA 或 Eclipse 中创建 Remote Debug 配置,填入远程服务器 IP 和端口 5005。连接建立后,再访问目标 JSP 页面,就可以像本地调试一样命中断点、查看变量和调用栈。

这种方式最适合排查“只在线上发生”的环境差异问题,例如服务器配置不同、依赖版本差异,或者某些请求数据在测试环境根本出现不了。

一套更实用的排查顺序

如果你不想在每次报错时都从头试一遍,可以按下面这个顺序处理:

  1. 先看 catalina.out 和系统日志,确认是编译错误、运行异常还是资源问题;
  2. 用 System.out.println() 和 tail -f 快速验证变量和执行路径;
  3. 若出现卡顿、阻塞或无响应,再用 jstack 看线程;
  4. 若怀疑内存泄漏或 GC 异常,再用 jmap、jstat 和 GC 日志继续分析;
  5. 需要精确跟踪代码执行时,切到 IDE 断点调试;
  6. 问题只出现在远程服务器时,再启用远程调试。

这样处理的好处是,先用成本最低的手段排掉大部分常见问题,再逐步进入更重的调试工具,效率通常更高。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表