具有许多 HTTP 请求的 PL/SQL 过程片段的性能和影响

问题描述 投票:0回答:1

我在 Oracle 数据库中有一个 PL/SQL 过程,它使用游标处理“PAYMENTS”表中的数据,并对外部 api 执行 HTTP 请求以检索 xml 形式的相关数据。然后该过程解析 XML 并将数据保存到另一个表中。这是代码的简化版本:

CREATE OR REPLACE PROCEDURE ... IS
  CURSOR TRANSACTIONS IS SELECT ... FROM PAYMENTS WHERE ...
  C1 TRANSACTIONS%ROWTYPE;
  URL VARCHAR2(...);
  L_XMLTYPE ...
BEGIN
  URL := 'http://...'
   
  OPEN TRANSACTIONS;
  
  LOOP -- COULD BE 10000 ROWS OR MANY MORE
    FETCH TRANSACTIONS INTO C1;
    EXIT WHEN C%NOTFOUND;  
      
    MY_SCHEMA.MY_PACKAGE.MAKE_HTTP_REQUEST_TO_API(URL, C1.ID, RESPONSE_XML);

    -- PARSE RESPONSE XML
    L_XMLTYPE := XMLTYPE(LV_RESPONSE_DATA);

    SELECT
       EXTRACTVALUE(L_XMLTYPE, ...) AS ...
       ...
       INTO ...
    FROM DUAL;

    -- SAVE DATA FROM RESPONSE XML

    INSERT ...

  END LOOP;
        
  CLOSE TRANSACTIONS;
END;

我想了解此过程的潜在性能影响以及任何其他相关注意事项如何测量它们?

因为该过程会发出 HTTP 请求并等待响应,然后再继续下一行。 可能会发生哪些具体问题?

注意:该 API 旨在返回每行数据且无法更改。

我找到了像wireshark这样的工具来测量网络问题,但我仍然不知道如何有效地使用它。我已经阅读了有关异步和同步 http 调用以及如何阻止主线程的信息。但我不确定它如何应用于 Oracle 上下文。

oracle performance-testing database-performance
1个回答
1
投票
  1. 网络呼叫很容易被防火墙或网络阻止软件或路由问题阻止,并且永远不会返回。您想对此进行测试以查看 sqlnet 超时是否有效,但即使如此,也不能完全信任它。我见过很多在外部网络调用中丢失的孤立会话。这将导致无限期地挂起锁、撤消和其他资源。您可能需要一个单独的异步监视进程来检测这一点,并在进程卡住时终止该进程。

  2. 当 Oracle 等待 http 请求返回时,它将报告其事件为

    TCP Socket (KGAS)
    。您可以在
    v$session
    中看到当前正在等待的会话,或者在 ASH (
    v$active_session_history
    ) 中看到过去的会话。您可以采样
    v$session
    或使用 Oracle 在 ASH 中按等待事件分组的 1 秒采样,以查看您的过程有多少是在等待网络、CPU 以及数据库内的其他工作。

  3. 只要存在对 Oracle 数据库外部异构事物的依赖(例如网络调用),就不建议在这些外部调用之间保持事务打开。如果您成为孤儿,或者外部代理需要很长时间才能做出响应,您可能会无限期地阻止其他人。我建议在

    COMMIT
    之后在循环内添加一个
    INSERT
    。如果您需要事务控制,以便错误应该回滚all插入(我猜不太可能),那么安全的解决方法是使用临时表,随时提交,然后您可以执行单个
    INSERT SELECT
    进入决赛桌。

  4. 还建议在外部调用之间尽可能少地进行本地工作,以便您可以尽快摆脱对远程源的依赖。 Oracle 数据库之间的数据库链接也是如此。网络中断的可能性会提高该部分代码的风险级别,因此您希望快速使用网络,然后再完成它。尝试将任何繁重的本地工作推迟到之后,这样就不再容易受到网络问题的影响。

  5. 考虑添加异常处理。如果 http 请求(或 XML 解析)失败并引发某种异常,您是否希望整个程序中止,或者您是否希望记录它并继续下一条记录并处理有效的内容?如果是后者,您需要使用异常处理程序将调用包装在匿名块中:

    LOOP
      BEGIN
        // http call
        // XML parse
        // something else that could fail
    
        COMMIT;
      EXCEPTION
        WHEN OTHERS THEN
          NULL; -- here you may log the error and the record that caused it. the loop will continue without aborting
      END;
    END LOOP;
    
  6. 对于往返客户端和数据库链接的正常网络流量,您还可以在

    v$sesstat
    中获得会话统计信息,提供传输至/来自这两个源的字节。但我不相信通过
    UTL_TCP
    的 TCP 套接字及其更高级别的包(如
    UTL_HTTP
    UTL_SMTP
    等)如此仪器化。我的数据表明没有任何
    v$sesstat
    统计数据可以跟踪流量。当然,您可以在操作系统上放置一个监视 shell 脚本,并每分钟运行一次
    netstat
    ,并在系统级别以这种方式收集 TCP 统计信息,但是您当然无法区分应用程序的工作和其他使用网络。您可以在 http 请求之前和之后使用
    SYSTIMESTAMP
    ,同时获取每个响应的
    LENGTH
    ,并创建您自己的指标来从过程内部监控吞吐量。

© www.soinside.com 2019 - 2024. All rights reserved.