Azure Function 内的 Oracle 连接超时在 5 分钟后取消

标签 oracle azure oracle11g azure-functions

我在 Java 函数中有以下代码行:

    try{

        context.getLogger().info("Paso001");
        Class.forName("oracle.jdbc.driver.OracleDriver"); 

        context.getLogger().info("Paso002");
        Connection conn = DriverManager.getConnection(
        params.get().getConnection(), params.get().getUser(), params.get().getPassword());

        if (conn != null) {
            context.getLogger().info("Connected to the database!");
        } else {
            context.getLogger().log(Level.SEVERE, "No connection to the database!");
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR).body("Error").build();
        } 
        
        context.getLogger().info("Paso003");
        PreparedStatement sentencia = conn.prepareStatement(params.get().getSentence());
        int index = 0;
        for (Param param : params.get().getParams()) {
            index++;
            if (param.getType().equals("String")) {
                sentencia.setString(index, param.getValue());
            } else {
                sentencia.setInt(index, Integer.parseInt(param.getValue()));
            }
        }
        ResultSet rs=sentencia.executeQuery();

        JSONArray result = JsonHelper.recordList2Json(rs);

        context.getLogger().info(result.toString());
        return request.createResponseBuilder(HttpStatus.OK).body(result.toString()).build();                
    } catch(Exception e)
    { 
        context.getLogger().info("Paso00-err");
        context.getLogger().log(Level.SEVERE, e.toString());
    }

日志仅显示“Paso001”和“Paso002”,但连接在 300000 毫秒(5 分钟)时失败,因为日志中未显示“Paso00-err”。我假设 Azure Function 已达到最大时间。

Azure Function 位于 VNET 集成内部,DATABASE 位于 ExpressRoute 后面的另一个本地 NET 内部。 我假设防火墙是正确的,因为在函数内打开到 Host:Port 的套接字似乎没问题:

  InetAddress IPv4 = null;
  try {
      IPv4 = InetAddress.getByName(connect.get().getHost());
  } catch (UnknownHostException e) {
      result = e.toString();
      e.printStackTrace();
      return request.createResponseBuilder(HttpStatus.OK).body(result.toString()).build();
  }


  try {
      Socket s = new Socket(IPv4, Integer.parseInt(connect.get().getPort()));
      result = "Server is listening on port " + connect.get().getPort()+ " of " + connect.get().getHost();
      context.getLogger().info(result);
      s.close();
  }
      catch (IOException ex) {
      // The remote host is not listening on this port
      result = "Server is not listening on port " + connect.get().getPort()+ " of " + connect.get().getHost();
      context.getLogger().info(result);
  }

结果得到:“服务器正在监听主机host的端口port

注意。我在指向本地安装的公共(public)数据库时遇到同样的错误。

还有什么东西没打开吗?有什么想法吗?

编辑:我用 .NET CORE 3.11 重写了代码...

        using (OracleCommand cmd = con.CreateCommand())
        {
            try
            {
                log.LogInformation("step001");
                con.Open();
                log.LogInformation("step002");
                cmd.BindByName = true;
                cmd.CommandText = sentence;
                OracleDataReader reader = cmd.ExecuteReader();
                log.LogInformation("step003");
                return new OkObjectResult(reader2Json(reader));
            }
            catch (Exception ex)
            {
                return new OkObjectResult("Error: "+ex.ToString());
            }
        }

和类似的结果,但这次抛出异常:

Error: Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out
   at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria)
   at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
   at Oracli2.Function1.Run(HttpRequest req, ILogger log) in C:\proy\vscode\dot2\Oracli2\Oracli2\Function1.cs:line 50

最佳答案

You can increase the function time out in the hosts.json file ,只是为了让您意识到这一点,但我不认为增加它会解决您的问题,5 分钟是一个慷慨的时间,除非您在此处运行的查询实际上需要超过 5 分钟才能返回!

您能否将连接字符串的 retry_count 和 retry_delay 设置得较小(例如:3 次尝试),以便您知道超时不是因为尝试进行 100 次重试而看不到实际的底层错误

其他问题可能与连接有关,最好的办法是进入控制台应用程序的 Kudu 控制台,打开 SSH 并通过 SSH 查看是否可以连接到 Oracle 数据库并从此处运行测试查询,如果一切都从这里开始,那么连接就不是问题。

enter image description here

enter image description here

关于Azure Function 内的 Oracle 连接超时在 5 分钟后取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73680742/

相关文章:

oracle - 如何在 PL/SQL 中将一纳秒添加到时间戳

sql - 如何检查oracle中长时间运行的插入进度

database - 将集群添加到oracle中的现有表

c# - 如何在 .NET Core 中将数据作为 Json 响应写入 HttpResponse

azure - 如何查看Azure系统默认路由

powershell - 获取 AzureNetworkSecurityGroup 不起作用

java - Flyway 在空模式上发现非空模式

sql - 如何按 ISO 周排序并从今天的周数开始

sql-server - 适合 Oracle 开发人员/dba 的 SQL Server

java - OracleCallableStatement V/S CallableStatement