首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

Tomcat 整合 MySQL 連線池:JNDI 資料源配置全攻略

     編輯:MySQL 綜合教學

Java Web 應用在 Tomcat 中使用資料庫連線池,標準做法是配置 JNDI DataSource,由容器管理連線生命週期,應用通過 JNDI 查找獲取連線。本文針對 Tomcat 8.5/9.0/10.1,詳解兩種主流配置方式、常見報錯排查與效能調優參數。

前置準備

  1. 將 MySQL JDBC 驅動 (`mysql-connector-j-8.x.jar` 或 `mysql-connector-java-5.1.x.jar`) 放入 `$CATALINA_HOME/lib/` 目錄(不要放在 WebApp 的 WEB-INF/lib)。
  2. 確認資料庫已建立、用戶權限正確、防火牆/安全組放行 3306。

方式一:全域資料源 — 在 server.xml 配置(所有 WebApp 可共用)

<!-- $CATALINA_HOME/conf/server.xml,在 <GlobalNamingResources> 區塊內 -->
<Resource
    name="jdbc/myapp"
    auth="Container"
    type="javax.sql.DataSource"
    driverClassName="com.mysql.cj.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=Asia/Taipei&allowPublicKeyRetrieval=true"
    username="app_user"
    password="StrongPassword!"
    maxTotal="50"
    maxIdle="20"
    minIdle="5"
    maxWaitMillis="10000"
    validationQuery="SELECT 1"
    testOnBorrow="true"
    testWhileIdle="true"
    timeBetweenEvictionRunsMillis="30000"
    minEvictableIdleTimeMillis="60000"
    removeAbandonedOnBorrow="true"
    removeAbandonedTimeout="60"
    logAbandoned="true"
/>

然後在同檔案的 `` -> `` -> `` 或全域 `` 區塊加入連結:

<ResourceLink
    name="jdbc/myapp"
    global="jdbc/myapp"
    type="javax.sql.DataSource"
/>

方式二:應用專屬資料源 — 在 context.xml 配置(隔離性更好,推薦)

選項 A:Tomcat 全域 context.xml(`$CATALINA_HOME/conf/context.xml`)

<Context>
  <Resource
      name="jdbc/myapp"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.cj.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=Asia/Taipei"
      username="app_user"
      password="StrongPassword!"
      maxTotal="50"
      maxIdle="20"
      minIdle="5"
      maxWaitMillis="10000"
      validationQuery="SELECT 1"
      testOnBorrow="true"
      testWhileIdle="true"
  />
</Context>

選項 B:WebApp 專屬 META-INF/context.xml(`src/main/webapp/META-INF/context.xml`,隨 WAR 部署,最推薦)

<Context antiResourceLocking="true">
  <Resource
      name="jdbc/myapp"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.cj.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=Asia/Taipei"
      username="app_user"
      password="StrongPassword!"
      maxTotal="30"
      maxIdle="15"
      minIdle="3"
      maxWaitMillis="5000"
      validationQuery="SELECT 1"
      testOnBorrow="true"
  />
</Context>

Spring / Spring Boot 整合範例

# application.yml (Spring Boot 2.x/3.x)
spring:
  datasource:
    jndi-name: java:comp/env/jdbc/myapp
    # 若不想用 JNDI,直接配置 HikariCP 參數即可,無需 Tomcat DataSource
    # hikari:
    #   maximum-pool-size: 30
    #   minimum-idle: 5
    #   ...

# 使用方式同普通 DataSource
@Autowired
private DataSource dataSource;

// 或注入 JdbcTemplate / EntityManager / SqlSessionFactory

常見報錯與排查

錯誤訊息原因解決
Cannot create JDBC driver of class '' for connect URL 'null'Resource 定義未生效、名稱不匹配、context.xml 未被讀取檢查 Resource name 與 lookup 名稱一致;確認 context.xml 位置正確;Tomcat 重啟後查看管理介面 Resources 頁面
Name [jdbc/myapp] is not bound in this ContextJNDI 名稱錯誤、未宣告 resource-refweb.xml 宣告 `jdbc/myappjavax.sql.DataSourceContainer`;代碼用 `java:comp/env/jdbc/myapp` 查找
Communications link failure網路不通、MySQL bind-address、防火牆、SSL 協商失敗測試 `telnet host 3306`;MySQL `bind-address=0.0.0.0`;URL 加 `useSSL=false` 或配置信任憑證
Public Key Retrieval is not allowedMySQL 8.0 caching_sha2_password 需公開金鑰URL 加 `allowPublicKeyRetrieval=true` 或改用 `mysql_native_password`
Connection has been abandoned連線洩漏(未 close、事務未提交/回滾)啟用 `removeAbandonedOnBorrow=true`;代碼確保 try-with-resources 關閉連線;排查長事務
Pool exhausted / maxWaitMillis timeout連線池耗盡、洩漏、或 maxTotal 太小監控 `numActive`/`numIdle`;調大 maxTotal;修復洩漏;優化慢查詢釋放連線

關鍵調優參數說明

  • maxTotal:最大連線數,參考 `max_connections`、應用執行緒數、DB 承受能力。公式參考:`(核心數 * 2) + 有效磁碟數` 或壓測得出。
  • maxIdle / minIdle:空閒連線上下限,避免頻繁建銷連開銷。
  • validationQuery + testOnBorrow:借用前驗證連線有效,防「斷線存活」。MySQL 8.0+ 建議 `SELECT 1`。
  • testWhileIdle + timeBetweenEvictionRunsMillis:背景線程定期清理失效空閒連線。
  • removeAbandonedOnBorrow:強制回收被遺棄連線(慎用,可能誤傷長查詢)。

最佳實踐清單

  1. **生產環境強制使用 JNDI + 容器管理連線池**,避免應用層重複造輪子。
  2. **密碼不寫在設定檔**:使用 Tomcat `PasswordCallbackHandler`、環境變數、Vault/K8s Secret 注入。
  3. **監控連線池指標**:整合 Prometheus JMX Exporter 或 Actuator `/metrics`,關注 `hikaricp.connections.active/idle/pending`。
  4. **定期壓測驗證參數**:用 JMeter/Locust 模擬峰值流量,觀察連線等待、DB CPU、回應延遲。
  5. **避免在 Tomcat 共用連線池給異構應用**:各應用獨立 DataSource,故障隔離、配置解耦。

連線池是 Java Web 與資料庫的「生命線」。配置規範、參數合理、監控到位,才能在高併發下穩如磐石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved