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

Tomcat 9 Linux环境下Servlet无法与PostgreSQL建立连接求助

排查Tomcat 9 + PostgreSQL连接无响应问题

看起来你遇到了跨环境部署后数据库连接阻塞的棘手问题——本地Tomcat 8正常运行,到了远程Linux的Tomcat 9就卡在连接创建步骤,无输出也无报错。结合你的描述和代码,我给你几个针对性的排查方向:

1. 先确认远程服务器到PostgreSQL的网络连通性

这是最常见的诱因,本地能连不代表远程服务器能访问数据库端口:

  • 登录到Linux服务器,用命令测试端口连通性:
    # 用telnet测试
    telnet 192.168.0.130 5432
    # 或者用nc(如果已安装)
    nc -zv 192.168.0.130 5432
    
    如果不通,需要调整两个PostgreSQL配置:
    • 修改postgresql.conf,把listen_addresses设为*(允许所有IP访问),然后重启PostgreSQL服务。
    • 修改pg_hba.conf,添加一行允许远程服务器IP访问的规则:
      host    mydb     root     你的远程服务器IP/32     md5
      
      之后执行pg_ctl reload重载配置。

2. 检查PostgreSQL驱动的放置位置和版本

Tomcat 9对JDBC驱动的加载逻辑和Tomcat 8略有不同,别踩这个细节坑:

  • 不要把驱动放在WEB-INF/lib下,Tomcat 9建议将PostgreSQL的JDBC驱动(比如postgresql-42.x.x.jar)放到TOMCAT_HOME/lib目录下,否则可能出现类加载冲突导致静默阻塞。
  • 确认驱动版本和PostgreSQL服务器版本兼容:比如PostgreSQL 12+建议用42.2及以上版本的驱动,版本不匹配也可能引发奇怪的连接问题。

3. 统一连接方式:别混用DriverManager和容器DataSource

你在web.xml里配置了<resource-ref>,但代码里却用DriverManager直连,这两种方式完全独立,相当于白配了resource-ref。不如改成Tomcat推荐的容器管理DataSource,既规范又能避免直连的隐患:

配置步骤:

  1. 在Tomcat的conf/context.xml(全局生效)或者你的Web应用的META-INF/context.xml(仅当前应用生效)里添加数据源配置:
<Resource name="jdbc/mydb"
          auth="Container"
          type="javax.sql.DataSource"
          driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://192.168.0.130:5432/mydb"
          username="root"
          password="root"
          maxTotal="100"
          maxIdle="30"
          maxWaitMillis="10000"/>
  1. 修改Servlet代码,通过JNDI获取连接(**一定要加异常捕获!**之前的代码没捕获异常,卡住也看不到报错):
Connection con = null;
try {
    Context initCtx = new InitialContext();
    Context envCtx = (Context) initCtx.lookup("java:comp/env");
    DataSource ds = (DataSource) envCtx.lookup("jdbc/mydb");
    out.println("<before create connection");
    con = ds.getConnection();
    out.println("connection created");
} catch (Exception e) {
    // 把异常打印到页面或者日志里,方便排查
    e.printStackTrace(out);
} finally {
    // 别忘了关闭连接,避免资源泄漏
    if (con != null) {
        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
  1. 确保web.xml里的<res-ref-name>和上面配置的name完全一致(比如都是jdbc/mydb)。

4. 给连接添加超时限制,避免无限阻塞

如果暂时不想改连接方式,可以给DriverManager加登录超时,这样超过时间会抛出异常,而不是一直卡住:

// 设置10秒连接超时
DriverManager.setLoginTimeout(10);
con = DriverManager.getConnection("jdbc:postgresql://192.168.0.130:5432/mydb","root", "root");

5. 查看Tomcat日志找隐藏异常

别只盯着页面输出,去远程服务器的TOMCAT_HOME/logs目录下看catalina.out或者localhost.log,里面可能有你看不到的异常信息——比如驱动找不到、权限不足、JNDI配置错误等,这些都可能导致程序静默失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:59:12