为啥我的 PHP 5.4 网络服务器无法使用 SQL Always On 与我的多子网故障转移集群通信?

Posted

技术标签:

【中文标题】为啥我的 PHP 5.4 网络服务器无法使用 SQL Always On 与我的多子网故障转移集群通信?【英文标题】:Why can't my PHP 5.4 webserver speak to my multi-subnet failover cluster using SQL Always On?为什么我的 PHP 5.4 网络服务器无法使用 SQL Always On 与我的多子网故障转移集群通信? 【发布时间】:2013-12-04 11:09:07 【问题描述】:

我们最近实施了 SQL Server 2012 Always On 故障转移集群。上线时间为 2 周,并且出现了一些令人担忧的问题。 以前我们处理的是同一子网中的服务器,但后来我们将服务器移动到了多个子网。既然这样做了,我们就遇到了多子网故障转移问题; http://technet.microsoft.com/en-us/library/ff878716.aspx。

“在多子网配置中,网络名称的在线和离线 IP 地址都将在 DNS 服务器上注册。客户端应用程序然后从 DNS 服务器检索所有注册的 IP 地址并尝试连接到这些地址按顺序或并行。这意味着多子网故障转移中的客户端恢复时间不再取决于 DNS 更新延迟。

默认情况下,客户端会按顺序尝试 IP 地址。当客户端在其连接字符串中使用新的可选 MultiSubnetFailover=True 参数时,它将改为同时尝试 IP 地址并连接到第一个响应的服务器。这有助于在发生故障转移时最大限度地减少客户端恢复延迟。”

问题的症状是:php 5.4 服务器将间歇性地无法连接。它可能工作 20 分钟,然后失败 25 分钟,然后工作 40 分钟。

我们尝试过这样引入“MultiSubnetFailover”参数:

$dbhandle = sqlsrv_connect(
    $myServer,
    array("UID"=>$myUser, "PWD"=>$myPass, "Database"=>$myDB, 'ReturnDatesAsStrings'=> true,
    'MultiSubnetFailover'=> true)
   )

并使用明确支持多子网故障转移的 Microsoft SQL 驱动程序更新网络服务器; http://blogs.msdn.com/b/sqlphp/archive/2012/03/07/microsoft-drivers-3-0-for-php-for-sql-server-released-to-web.aspx

子网设置正确,当我提供“MultiSubnetFailover=Yes”参数时,我可以通过 SQL Server Management Studio 等其他服务正常连接,实际上区别是白天和黑夜。

感谢任何帮助,这个太接近发布了,不方便。

编辑:实际上我错过了第二个连接字符串,但是一旦使用多子网故障转移参数配置它,错误仍然会发生;

   $pdoHandle = new PDO("sqlsrv:server=$myServer;database=$myDB;multiSubnetFailover=yes", $myUser, $myPass);

【问题讨论】:

您的日志中有任何相关内容吗?不幸的是,不熟悉 MS 环境 - 您有哪些支持选项? 在日志记录方面,我们遇到了似乎是超时的连接错误,“由于打开服务器连接延迟,无法完成登录过程”。我们还设置了一个脚本来发送 HTTP 请求并记录服务器何时发生故障。从这里我可以看到它今天早上从 9:52 到 10:09 成功,然后失败到 10:28,成功到 10:37,失败到 10:46.. 不过,我怀疑是否存在有用的模式。我们与 Microsoft 没有任何支持合同。 好的。是否值得尝试不同版本的 5.4?你没有说你正在使用哪个,所以我假设是最新的 - 可能会降低几个小版本?另外,如果你卡住了,看看最新的 5.5 是否表现出相同的行为? 不是丢失了一些网络配置,例如防火墙规则或丢失的路由或类似的东西吗? 这绝对是服务器的问题,因为当我将它指向不同的数据库服务器(在同一网络中)时,它可以工作。我将尝试不同版本的 PHP,但我认为驱动程序是嫌疑人 【参考方案1】:

这是一个没有太多文档的尴尬问题,但我们确实找到了解决方案。 SQLSRV_Connect 参数应为

'MultiSubnetFailover'=> "Yes"

而不是“真实”。因为 true 只返回一个布尔值,而它需要一个字符串。对于 PDO 接口使用的连接字符串,以下语法似乎对我们有用:

"MultiSubnetFailover=True" 

但即使您使用正确的语法,支持也不是很好。如果此解决方案不起作用,那么您需要增加连接超时,因为 SQL Server 驱动程序将依次尝试每个 DNS 记录。我们使用“LoginTimeout=75”(秒)来设置 2 个子网,而 110 应该用于设置 3 个子网。

然而,这个解决方案仍然很糟糕。它适用于只需要连接一次并从那时起使用相同连接的前端应用程序。对于倾向于为每个请求创建新连接的 Web 服务器来说,它并不能很好地工作。它可以使每个网页的加载时间长达 30、70 或 100 秒,具体取决于当时如何配置 DNS 记录。

【讨论】:

以上是关于为啥我的 PHP 5.4 网络服务器无法使用 SQL Always On 与我的多子网故障转移集群通信?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Xampp Apache 服务器无法打开一个 PHP 脚本?

php 5.4 异常字符集

php artisan migrate 不适用于 Laravel 5.4 中的 XAMPP

为啥我的手机显示无法连接到服务器

在 PHP 5.4 中设置 PHP-FPM

为啥 PHP 无法从 Js FormData fetch 中获取 $_POST 数据?