我有一种情况,我们有两个生产数据库,彼此同步。 Server One被认为是主要的。有时由于维护或灾难,服务器二将成为主要的。
在我们的一些代码中,这意味着我们必须手动进入并编辑数据库连接的服务器名称。我发现这很烦人,所以我写的最后一件事我把两者的服务器信息都设置了一个循环。如果服务器One上的oci_connect失败3次,它将转移到服务器2。如果服务器2失败了3次,它将通知用户无法建立连接。
在大多数情况下,我们都有切换服务器的情况。例如,昨天,它运作良好。今天它没有。它只是无休止地坐着旋转。 PHP错误日志中没有错误。没有失败的继续。没有错误输出到屏幕。 5分钟没什么。
然后我不得不手动编辑愚蠢的配置文件。
我问可能有什么不同,我被告知“昨天数据库已关闭,但服务器没有。今天服务器已关闭。”好的...?但我没有看到区别。如果无法与服务器建立任何类型的通信,我希望oci_connect返回false。我希望它超时和错误。当它从服务器收到错误代码时,不仅传递它。如果出现网络问题怎么办?
这是oci_connect中的错误还是有可能我们的PHP配置中的某些东西给oci_connect一个疯狂的长时间超时?
如果它是某种“bug”,我可以通过某种方式检查服务器是否先出现?像ping一样? (当然,当我通过命令提示符执行ping操作时,我得到了Server One的响应,然后被告知,“它现在已经回来了”,尽管我对此时间持怀疑态度。)
无论如何,如果有人能够阐明为什么oci_connect可能会无休止地运行而且如何防止这种情况发生,我将不胜感激。
- 编辑: 我的代码在某些循环中看起来就像PHP.net上的示例一样。
$count = count($servers);
for($i = 0; $i < $count; $i++){
if((!isset($connection)) || ($connection == false)){
// Attempt to connect to the oracle database
$connection = @oci_connect($servers[$i]["user"], $servers[$i]["pass"], $servers[$i]["conid"]) or ($conn_error = oracle_error());
// Try again if there was a failure
if(($connection == false) || (isset($con_error))){
// Three (two more) tries per alternative
for($j = $st; $j < $fn; $j++){
// Try again to connect
$connection = @oci_connect($servers[$i]["user"], $servers[$i]["pass"], $servers[$i]["conid"]) or ($conn_error = oracle_error());
} // for($j = 2; $j < 4; $j++)
} // if($connection == false)
} // if(!isset($connection) || ($connection == false))
} // for($i = 0; $i < $count; $i++)
答案 0 :(得分:3)
你能证实它没有返回假吗?在等待连接时它可能只是阻塞吗? (如果你做var_dump(oci_connect(...))
会怎么样?
直接来自php.net的documentation:
如果要指定连接 有网络时超时 问题,你可以编辑客户端 (例如PHP方面)sqlnet.ora文件和 设置SQLNET.OUTBOUND_CONNECT_TIMEOUT。 这设置了上限时间 建立连接权 通过DB,包括时间 试图连接到其他人 服务。它可以从 Oracle 10.2.0.3以后。
在Oracle 11.1中,略有一点 重量轻的解决方案 引入了TCP.CONNECT_TIMEOUT。 它也是一个sqlnet.ora参数。它 仅限于TCP连接 建立时间,主要是 可以看到连接问题。
客户端sqlnet.ora文件应该是 放在同一目录下 tnsnames.ora文件。
此外,您可能想查看FAN on this page ...看起来它可能完全符合您的要求(但我没有经验,所以我不确定它是否真的适合您)。