Domino/Notes执行Informix JDBC查询时nhttp CPU占用过高
看起来你遇到的核心问题是Informix JDBC驱动的后台清理线程在Domino环境下无法正确释放,再加上代码里的资源管理小问题,共同导致了nhttp进程CPU占用过高且线程无法回收。以下是针对性的解决方案:
1. 修正代码中的资源释放逻辑
你的代码存在变量作用域和多线程安全问题:如果ResultSet rs、Statement stmt和Connection conn是类成员变量,在多线程的Domino环境下会引发资源竞争;即使是方法内声明,当前写法也会导致finally块无法正确访问这些变量(编译时会报错)。正确的做法是把这些变量声明在方法顶部,并严格按照ResultSet → Statement → Connection的顺序关闭资源:
public void InformixSQLRS() { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // 添加IFX_PREPARE_CACHE=0关闭预编译语句缓存,避免清理线程启动 String url = "jdbc:informix-sqli://IPADDRESSHERE:PORTHERE/db_cra:INFORMIXSERVER=SERVERNAME;user=USERNAME;password=PASSWORD;IFX_PREPARE_CACHE=0"; Class.forName("com.informix.jdbc.IfxDriver"); conn = DriverManager.getConnection(url); System.out.println("After getting Driver"); String selectSQL = "SELECT FIRST 10 * FROM RtCSQsSummary "; String orderbySQL = "ORDER BY startdatetime DESC"; String strsql = selectSQL + orderbySQL; stmt = conn.createStatement(); System.out.println(strsql); rs = stmt.executeQuery(strsql); System.out.println("after executeQuery"); ResultSetMetaData rsmd = rs.getMetaData(); int ncols = rsmd.getColumnCount(); for (int i = 1; i < ncols; i++) { System.out.println(rsmd.getColumnLabel(i) + " " + rsmd.getColumnType(i)); } } catch (SQLException e) { System.out.println("ERROR: failed to connect!"); System.out.println("ERROR: " + e.getMessage()); e.printStackTrace(); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } finally { // 按顺序关闭资源,每个操作单独捕获异常避免影响后续关闭 try { if (rs != null) { rs.close(); } } catch (SQLException se) { se.printStackTrace(); } try { if (stmt != null) { stmt.close(); } } catch (SQLException se) { se.printStackTrace(); } try { if (conn != null) { conn.close(); } } catch (SQLException se) { se.printStackTrace(); } System.out.println("Goodbye! (finally)"); } System.out.println("Last call"); }
2. 关闭Informix驱动的预编译语句缓存
在JDBC URL中添加IFX_PREPARE_CACHE=0参数,这会直接禁用Informix驱动的PreparedStatement缓存机制,从而避免Informix-PreparedStatementCacheCleanupThread后台线程的启动——这正是你观察到的CPU占用过高的核心元凶。
3. 统一驱动Jar包的存放位置
不要同时把Informix JDBC驱动放在Domino的Jars元素和WebContent/WEB-INF/lib目录下,这会导致类加载冲突,驱动的线程无法被正确回收。建议选择以下一种方式:
- 将驱动Jar包放在Domino服务器的
jvm/lib/ext目录下(全局生效,适合多个应用共享) - 仅放在当前NSF的
WebContent/WEB-INF/lib目录下(仅当前应用生效)
4. 升级Informix JDBC驱动版本
你当前使用的jdbc-4.10.8.1.jar版本相对较老,可能存在与Domino 9.0.1 JVM(Java 7)的兼容性问题。建议升级到兼容JDBC 4.1的较新版本(比如4.50.11或更高,注意选择对应Java 7的版本),新版本通常会修复线程管理和资源回收的bug。
5. 优化Domino JVM参数(可选)
如果上述步骤仍未解决问题,可以调整Domino的JVM参数,优化线程和GC行为:
- 在Domino服务器的
notes.ini中添加JavaMaxHeapSize=1024m(根据服务器配置调整,增大堆内存) - 添加
JavaVerboseGC=1查看GC日志,确认是否存在GC频繁导致的CPU飙升
按照这些步骤逐一排查,应该能解决nhttp进程CPU占用过高且线程无法释放的问题。
内容的提问来源于stack exchange,提问作者Brian M Moore

