为什么可以';我的PHP 5.4 Web服务器使用SQL Always-On与多子网故障转移群集通信


Why can't my PHP 5.4 webserver speak to my multi-subnet failover cluster using SQL Always On?

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

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

默认情况下,客户端按顺序尝试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驱动程序更新Web服务器;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)正常连接,事实上,不同之处在于night&白天

感谢任何帮助,这一次离发布太近了。

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

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

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

'MultiSubnetFailover'=> "Yes"

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

"MultiSubnetFailover=True" 

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

然而,这个解决方案仍然是垃圾。它适用于只需要连接一次并从此使用相同连接的前端应用程序。它不适用于倾向于为每个请求创建新连接的web服务器。它可能会使加载每个网页花费长达30、70或100秒的时间,这取决于当时DNS记录的配置方式。