Oracle 连接池(Connection Pooling)与 DRCP
Oracle 连接池(Connection Pooling)与 DRCP
适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
连接池(Connection Pooling) 通过复用数据库连接,减少连接建立开销[1]:
| 方案 | 实现层 | 适用场景 |
|---|---|---|
| 应用层连接池 | 应用(Tomcat/HikariCP) | 通用 |
| 共享服务器(Shared Server) | 数据库 | 中等连接数 |
| DRCP | 数据库 | 海量短连接 |
| CMAN Multiplexing | 中间层 | 多路复用 |
2. 应用层连接池
2.1 工作原理
应用启动 → 创建 N 个数据库连接 → 放入连接池
│
▼
应用请求 → 从池中取连接 → 执行 SQL → 归还连接到池
2.2 HikariCP 配置示例(Java)
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:oracle:thin:@//dbhost:1521/orcl");
config.setUsername("scott");
config.setPassword("tiger");
// 连接池配置
config.setMaximumPoolSize(20); // 最大连接数
config.setMinimumIdle(5); // 最小空闲
config.setConnectionTimeout(30000); // 连接超时 30 秒
config.setIdleTimeout(600000); // 空闲超时 10 分钟
config.setMaxLifetime(1800000); // 连接最长生命 30 分钟
HikariDataSource ds = new HikariDataSource(config);
2.3 优缺点
优点:
- 应用层控制
- 灵活配置
- 性能高
缺点:
- 每个应用独立
- 进程数仍较多(每个应用 N 个连接)
3. 数据库共享服务器(Shared Server)
3.1 工作模型
客户端 1 ─┐
客户端 2 ─┼─> Dispatcher ─> Request Queue ─> Shared Server 1
客户端 3 ─┤ ─> Shared Server 2
客户端 N ─┘ └> Shared Server 3
└> Response Queue ─> Dispatcher ─> 客户端
3.2 配置
ALTER SYSTEM SET shared_servers=5 SCOPE=BOTH;
ALTER SYSTEM SET max_shared_servers=20 SCOPE=BOTH;
ALTER SYSTEM SET dispatchers='(PROTOCOL=TCP)(DISPATCHERS=3)' SCOPE=BOTH;
ALTER SYSTEM SET shared_server_sessions=200 SCOPE=BOTH;
详细内容见:Oracle 进程模型:专用 vs 共享服务器。
4. DRCP(Database Resident Connection Pool)
4.1 概念
11g 引入,数据库驻留连接池,比共享服务器更高效[2]:
客户端 1 ─┐
客户端 2 ─┼─> Connection Broker ─> Pool Servers(4-100 个)
客户端 3 ─┤
客户端 N ─┘
4.2 DRCP vs 共享服务器
| 维度 | 共享服务器 | DRCP |
|---|---|---|
| 粒度 | SQL 语句级 | 会话级 |
| 复用 | 多客户端轮流使用 | 池化复用 |
| 适用 | 中等连接数 | 海量短连接 |
| 客户端支持 | 需配置 tnsnames | OCI/JDBC 直接支持 |
| 进程数 | Dispatcher + Shared Server | Broker + Pool Server |
4.3 DRCP 配置
-- 启动 DRCP
EXEC DBMS_CONNECTION_POOL.START_POOL;
-- 配置池参数
EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
param_name => 'MINSIZE',
param_value => '4'
);
EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
param_name => 'MAXSIZE',
param_value => '100'
);
EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
param_name => 'INACTIVITY_TIMEOUT',
param_value => '300'
);
EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
param_name => 'MAX_THINK_TIME',
param_value => '120'
);
-- 查看状态
SELECT connection_pool, status, MINSIZE, MAXSIZE
FROM dba_cpool_info;
4.4 客户端使用
# tnsnames.ora 指定 POOL
ORCL_DRCP =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = POOLED) # 使用 DRCP
(SERVICE_NAME = orcl)
)
)
# 连接
sqlplus scott/tiger@orcl_drcp
4.5 Java 使用 DRCP
// JDBC 连接字符串
String url = "jdbc:oracle:thin:@//dbhost:1521/orcl?oracle.jdbc.ReadTimeout=60000";
Properties props = new Properties();
props.setProperty("user", "scott");
props.setProperty("password", "tiger");
// 启用 DRCP
props.setProperty("oracle.jdbc.v8styleConnectionPool", "true");
Connection conn = DriverManager.getConnection(url, props);
4.6 DRCP 监控
-- 池状态
SELECT
connection_pool,
status,
MINSIZE,
MAXSIZE,
SESSION_CACHED_CUR
FROM dba_cpool_info;
-- 池统计
SELECT
POOL_NAME,
NUM_OPEN_SERVERS,
NUM_REQUESTS,
NUM_HITS,
NUM_MISSES
FROM v$cpool_stats;
-- 池连接详情
SELECT
SESSKEY,
STATE,
SERVER_NAME,
PROGRAM
FROM v$cpool_conn_info;
5. Connection Manager(CMAN)Multiplexing
5.1 概念
CMAN 在中间层多路复用多个客户端连接,减少数据库端进程数。
5.2 配置
# cman.ora
CMAN =
(ADDRESS=(PROTOCOL=TCP)(HOST=cman_host)(PORT=1630))
CMAN_PROFILE =
(PARAMETER_LIST=
(MAXIMUM_RELAYS=128)
(LOG_LEVEL=1)
(MULTIPLEXING=ON)
(RELAY_STATISTICS=YES)
)
详细内容见:Oracle Connection Manager(CMAN)。
6. FCF(Fast Connection Failover)
6.1 概念
RAC + ONS(Oracle Notification Service)实现的快速故障切换。
6.2 配置
// Java 配置
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@//rac-scan:1521/orcl");
ods.setUser("scott");
ods.setPassword("tiger");
ods.setConnectionCachingEnabled(true);
ods.setFastConnectionFailoverEnabled(true);
Properties cacheProps = new Properties();
cacheProps.setProperty("MinLimit", "5");
cacheProps.setProperty("MaxLimit", "20");
cacheProps.setProperty("InitialLimit", "5");
cacheProps.setProperty("ConnectionWaitTimeout", "10");
ods.setConnectionCacheProperties(cacheProps);
7. 连接池选择
7.1 决策树
连接数 < 100:
→ 应用层连接池(HikariCP)
连接数 100-1000:
→ 应用层连接池 + 共享服务器
连接数 1000-10000+:
→ 应用层连接池 + DRCP
需要负载均衡:
→ RAC + FCF + SCAN
7.2 对比
| 方案 | 适用规模 | 实现复杂度 | 性能 |
|---|---|---|---|
| 应用层连接池 | 小-中 | 低 | 高 |
| 共享服务器 | 中 | 中 | 中 |
| DRCP | 大 | 中 | 高 |
| CMAN | 大 | 高 | 中 |
8. 常见坑与排错
8.1 ORA-12520: no available handler
现象:连接数过多,无可用处理进程。
修复:
-- 增大 PROCESSES
ALTER SYSTEM SET processes=500 SCOPE=SPFILE;
-- 重启生效
-- 或启用 DRCP/共享服务器
8.2 DRCP 连接失败
现象:ORA-56609: DRCP not started。
修复:
EXEC DBMS_CONNECTION_POOL.START_POOL;
SELECT status FROM dba_cpool_info;
8.3 连接泄漏
现象:连接数持续增长。
修复:
// 应用层确保连接关闭
try (Connection conn = ds.getConnection()) {
// 使用连接
} // 自动关闭
// 设置 maxLifetime 避免泄漏
config.setMaxLifetime(1800000);
8.4 连接超时
现象:连接等待时间长。
修复:
-- 检查等待事件
SELECT event, total_waits, time_waited
FROM v$system_event
WHERE event LIKE '%queue%';
-- 增加共享服务器
ALTER SYSTEM SET shared_servers=10 SCOPE=BOTH;
9. 最佳实践
- 应用层用 HikariCP:性能最佳
- 海量连接用 DRCP:减少进程数
- 中等连接用共享服务器:折中方案
- RAC 用 FCF:快速故障切换
- 合理设置连接数:避免过度
- 连接泄漏检测:定期监控
- 连接超时配置:避免资源耗尽
- 监控 v$session:发现异常连接
- DRCP 池大小动态调整:根据负载
- 应用与 DBA 协作:统一连接管理
10. 参考资料
[1] Oracle Database Net Services Administrator’s Guide 19c, “Connection Pooling” https://docs.oracle.com/en/database/oracle/oracle-database/19/netag/
[2] Oracle Database Administrator’s Guide 19c, “Database Resident Connection Pooling” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-processes.html