排查UTL_HTTP“过多未关闭HTTP请求”报错:如何查询开放请求?
排查UTL_HTTP "too many open HTTP requests" 问题的查询方法
以下是几个可以用来定位未关闭UTL_HTTP请求的查询和手段:
1. 查询会话关联的HTTP网络连接
通过v$session_connect_info视图关联会话的网络连接信息,筛选HTTP相关的端口或协议:
SELECT s.sid, s.serial#, s.username, sci.remote_host, sci.remote_port, sci.protocol FROM v$session s JOIN v$session_connect_info sci ON s.sid = sci.sid WHERE (sci.protocol LIKE 'HTTP%' OR sci.remote_port IN (80, 443, 8080)) -- 覆盖常见HTTP/HTTPS端口 AND s.username = 'YOUR_APP_USER'; -- 替换为你的应用用户
这个查询能直接找到会话对应的远程HTTP服务地址和端口,帮助定位未释放的连接。
2. 查找未关闭的UTL_HTTP请求游标
UTL_HTTP的请求调用(如UTL_HTTP.BEGIN_REQUEST)会生成对应的SQL游标,通过v$open_cursor可以追踪这些未关闭的请求:
SELECT s.sid, s.serial#, oc.sql_text, oc.last_active_time, oc.cursor_type FROM v$session s JOIN v$open_cursor oc ON s.sid = oc.sid WHERE oc.sql_text LIKE '%UTL_HTTP.BEGIN_REQUEST%' AND s.username = 'YOUR_APP_USER';
结合last_active_time可以判断哪些请求长时间未被关闭,cursor_type能区分是否为活跃游标。
3. 关联操作系统进程查看网络连接
如果数据库视图信息不足,可以通过v$process获取会话对应的操作系统进程ID,再到系统层面查询开放连接:
SELECT s.sid, s.serial#, p.spid, s.module, s.action FROM v$session s JOIN v$process p ON s.paddr = p.addr WHERE s.username = 'YOUR_APP_USER' AND s.program LIKE '%oracle%';
拿到spid后,在操作系统执行对应命令:
- Linux:
netstat -anp | grep <spid> - Windows:
netstat -ano | findstr <spid>
这样就能看到该Oracle进程所有的开放网络连接,包括未关闭的HTTP连接。
4. 启用UTL_HTTP调试日志追踪请求生命周期
如果上述查询仍无法定位,开启UTL_HTTP的调试日志,记录每个请求的创建和关闭动作:
BEGIN UTL_HTTP.SET_DEBUG_LEVEL(4); -- 4为详细调试级别,包含请求生命周期日志 UTL_HTTP.SET_DEBUG_OUTPUT(UTL_FILE.FOPEN('UTL_HTTP_LOG_DIR', 'utl_http_trace.log', 'W')); END; /
注意:需要先创建UTL_HTTP_LOG_DIR目录对象并授予应用用户UTL_FILE权限,日志会记录每个BEGIN_REQUEST和END_REQUEST的调用,方便排查异常场景下未关闭的请求。
额外提示
- 确保代码在异常处理块中也调用
UTL_HTTP.END_REQUEST,避免因异常导致连接未释放; - 检查是否启用了UTL_HTTP连接池,可通过
UTL_HTTP.SET_CONNECTION_TIMEOUT设置连接超时时间,自动回收闲置连接。
内容的提问来源于stack exchange,提问作者ACFalcon
相关产品推荐
相关产品推荐

