我在 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 数据库并从此处运行测试查询,如果一切都从这里开始,那么连接就不是问题。
关于Azure Function 内的 Oracle 连接超时在 5 分钟后取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73680742/