JDBC 驱动程序对高可用性和灾难恢复的支持
本文介绍了 Microsoft JDBC Driver for SQL Server 对高可用性、灾难恢复(Always On 可用性组)的支持。 有关 Always On 可用性组的详细信息,请参阅 SQL Server 2012 (11.x) 联机丛书。
从 Microsoft JDBC Driver for SQL Server 4.0 版本开始,可以在连接属性中指定(高可用性、灾难恢复)可用性组 (AG) 的可用性组侦听器。 如果 Microsoft JDBC Driver for SQL Server 应用程序连接到进行故障转移的 Always On 数据库,则原始连接断开,且应用程序必须建立新的连接,以便在故障转移后继续运行。 {1}Microsoft JDBC Driver 4.0 for SQL Server{2} 中新增了以下连接属性:
multiSubnetFailover
applicationIntent
在连接到可用性组的可用性组侦听程序或故障转移群集实例时可指定 multiSubnetFailover=true。
注意
默认情况下 multiSubnetFailover 为 false。 使用 applicationIntent 声明应用程序工作负载类型。 有关详细信息,请参阅以下部分。
自 Microsoft JDBC Driver for SQL Server 版本 6.0 起,新增了连接属性 transparentNetworkIPResolution (TNIR),用于与 AlwaysOn 可用性组或关联有多个 IP 地址的服务器进行透明连接。 当 transparentNetworkIPResolution 为 true 时,驱动程序将尝试连接到可用的第一个 IP 地址。 如果第一次尝试失败,驱动程序将尝试并行连接到所有 IP 地址,直到超过超时时间,如果其中一次尝试成功,则放弃所有挂起的连接尝试。
注意:
- transparentNetworkIPResolution 默认情况下为 true
- 如果 multiSubnetFailover 为 true,则忽略 transparentNetworkIPResolution
- 如果使用数据库镜像,则忽略 transparentNetworkIPResolution
- 如果 IP 地址数超过 64 个,则忽略 transparentNetworkIPResolution
- 如果 transparentNetworkIPResolution 为 true,首次连接尝试使用 500 毫秒作为超时值。 其余的连接尝试将遵循与 multiSubnetFailover 功能相同的逻辑。
注意
如果使用的是 Microsoft JDBC Driver 4.2 for SQL Server(或更低版本),并且 multiSubnetFailover 为 false,则 Microsoft JDBC Driver for SQL Server 将尝试连接到第一个 IP 地址。 如果 Microsoft JDBC Driver for SQL Server 无法建立与第一个 IP 地址的连接,则连接将失败。 Microsoft JDBC Driver for SQL Server 将不会尝试连接到与此服务器关联的任何后续 IP 地址。
备注
增大连接超时值和实现连接重试逻辑将增加应用程序连接到可用性组的概率。 此外,由于可用性组进行故障转移而可能使连接失败,您应实现连接重试逻辑,重试失败的连接,直至重新连接。
使用 multiSubnetFailover 进行连接
在连接到 SQL Server 2012 (11.x) 可用性组或 SQL Server 2012 (11.x) 故障转移群集实例的可用性组侦听程序时,应始终指定 multiSubnetFailover=true 。 multiSubnetFailover 可加快 SQL Server 2012 (11.x) 中所有可用性组和故障转移群集实例的故障转移速度,并且将显著缩短单子网和多子网 Always On 拓扑的故障转移时间。 在多子网故障转移过程中,客户端将尝试并行进行连接。 子网故障转移期间,Microsoft JDBC Driver for SQL Server 将积极地重试 TCP 连接。
multiSubnetFailover 连接属性指示应用程序正部署在某一可用性组或故障转移群集实例中,并且 Microsoft JDBC Driver for SQL Server 将尝试通过试图连接到所有 IP 地址来连接到主 SQL Server 实例上的数据库 。 如果对连接指定的是 MultiSubnetFailover=true ,客户端重试 TCP 连接尝试的速度快于操作系统的默认 TCP 重传间隔。 这种行为可以在 Always On 可用性组或 Always On 故障转移群集实例进行故障转移后更快地进行重新连接,并同时适用于单子网和多子网可用性组和故障转移群集实例。
有关 Microsoft JDBC Driver for SQL Server 中的连接字符串关键字的详细信息,请参阅设置连接属性。
如果在连接到非可用性组侦听程序或故障转移群集实例时指定 multiSubnetFailover=true,则可能会对性能造成负面影响,因此不支持这样做。
如果未安装安全管理器,默认情况下,Java 虚拟机将缓存虚拟 IP 地址 (VIP) 一段时间(由您的 JDK 实现和 Java 属性 networkaddress.cache.ttl 和 networkaddress.cache.negative.ttl 定义)。 如果已安装 JDK 安全管理器,默认情况下,Java 虚拟机将缓存 VIP 且不会刷新缓存。 您应将 Java 虚拟机缓存的“生存时间”(networkaddress.cache.ttl) 设置为“一天”。 如果未将默认值更改为“一天(左右)”,则添加或更新 VIP 后,不会清除 Java 虚拟机缓存中的旧值。 有关 networkaddress.cache.ttl 和 networkaddress.cache.negative.ttl 的详细信息,请参阅 https://download.oracle.com/javase/6/docs/technotes/guides/net/properties.html。
使用以下准则可以连接到可用性组或故障转移群集实例中的服务器:
如果在与 multiSubnetFailover 连接属性相同的连接字符串中使用 instanceName 连接属性,驱动程序将生成一个错误。 此错误反映了在可用性组中没有使用 SQL Browser 这一事实。 但如果另外指定了 portNumber 连接属性,驱动程序将忽略 instanceName 而使用 portNumber 。
连接到单子网或多子网时使用 multiSubnetFailover 连接属性,这二者的性能都会得到改进 。
若要连接到某一可用性组,请在您的连接字符串中将该可用性组的可用性组侦听器指定为服务器。 例如,jdbc:sqlserver://VNN1。
连接到配置有超过 64 个 IP 地址的 SQL Server 实例将导致连接失败。
基于以下身份验证类型,使用 multiSubnetFailover 连接属性的应用程序的行为不受到影响:SQL Server 身份验证、Kerberos 身份验证或 Windows 身份验证。
增加 loginTimeout 的值,以延长故障转移时间并减少应用程序连接重试次数 。
如果只读路由不起作用,则连接到可用性组中的辅助副本位置在以下情况下将失败:
如果未将辅助副本位置配置为接受连接。
如果应用程序使用 applicationIntent=ReadWrite(将在下文中介绍)并且次要副本位置被配置为只读访问 。
如果将主副本配置为拒绝只读工作负荷且连接字符串包含 ApplicationIntent=ReadOnly,连接将失败。
从数据库镜像升级到使用多子网群集
如果将当前使用数据库镜像的 Microsoft JDBC Driver for SQL Server 应用程序升级到多子网方案,应删除 failoverPartner 连接属性,并将它替换为已设置为“true” 的 multiSubnetFailover ,同时将连接字符串中的服务器名称替换为可用性组侦听程序。 如果连接字符串使用 failoverPartner 和 multiSubnetFailover=true,驱动程序将生成一个错误 。 但是,如果连接字符串使用 failoverPartner 和 multiSubnetFailover=false(或 ApplicationIntent=ReadWrite),则此应用程序将使用数据库镜像 。
如果数据库镜像在 AG 中的主数据库上使用,并且如果 multiSubnetFailover=true 用于连接到主数据库(而非可用性组侦听程序)的连接字符串中,驱动程序则将返回一个错误 。
指定应用程序意图
你可以在连接字符串中指定 ApplicationIntent
关键字。 可分配的值为 ReadWrite
(默认值)或 ReadOnly
。
当你设置 ApplicationIntent=ReadOnly
时,客户端将在连接时请求读取工作负荷。 服务器在连接时和在执行 USE
数据库语句期间强制执行此意图。
ApplicationIntent
关键字不适用于旧版只读数据库。
ReadOnly 的目标
如果连接选择 ReadOnly
,连接就会分配到数据库可能存在的下列任何特殊配置:
AlwaysOn。 数据库可允许或禁止目标可用性组数据库上的读取工作负载。 此选项通过使用
PRIMARY_ROLE
和SECONDARY_ROLE
Transact-SQL 语句的ALLOW_CONNECTIONS
子句进行控制。
如果这些特殊目标都不可用,则从常规数据库读取。
关键字 ApplicationIntent
启用只读路由。
只读路由
只读路由是一项功能,可用于确保数据库的只读副本的可用性。 若要启用只读路由,必须遵守以下所有要求:
必须连接到 AlwaysOn 可用性组侦听程序。
ApplicationIntent
连接字符串关键字必须设置为ReadOnly
。数据库管理员必须配置可用性组才能启用只读路由。
使用只读路由的多个连接可能不会全部连接到相同的只读副本。 对数据库同步进行更改或对服务器的路由配置进行更改可能导致客户端连接到不同的只读副本。
你可以确保所有只读请求都连接到相同的只读副本,方法是不将可用性组侦听程序传递到 Server
连接字符串关键字。 而是指定只读实例的名称。
只读路由可能比连接到主要副本需要更长的时间。 等待时间较长是因为只读路由首先会连接到主要副本,然后查找最合适的可读次要副本。 由于需要执行多个步骤,所以应将 login
超时时间增加到至少 30 秒。
连接池
将 Microsoft JDBC Driver for SQL Server 与连接池库结合使用时,应考虑以下几点:
- 如果你已配置只读路由,并且拥有一个想要在其中分配负载的只读服务器池,则连接池将减少新连接在目标服务器上分配的机会数。
- 若要避免池中任何单个服务器上的负载较高,请选择可促进在池中均匀分布连接的池选项。
- 确保连接池已配置了一个连接生存期。 如果在建立只读连接时一个只读副本不可用,该配置应确保连接最终被关闭,并且在只读副本再次可用时重新与它建立连接。
支持 multiSubnetFailover 和 applicationIntent 的新方法
使用以下方法,可以编程方式访问 multiSubnetFailover 、applicationIntent 和 transparentNetworkIPResolution 连接字符串关键字:
SQLServerDataSource.setTransparentNetworkIPResolution
SQLServerDataSource.getTransparentNetworkIPResolution
另外,getMultiSubnetFailover 、setMultiSubnetFailover 、getApplicationIntent 、setApplicationIntent 、getTransparentNetworkIPResolution 和 setTransparentNetworkIPResolution 方法也添加到 SQLServerDataSource 类、SQLServerConnectionPoolDataSource 类和 SQLServerXADataSource 类中。
TLS/SSL 证书验证
可用性组包含多个物理服务器。 {1}Microsoft JDBC Driver 4.0 for SQL Server{2} 添加了对 TLS/SSL 证书中“使用者可选名称 (SAN)”的支持,因此可以将多个主机与统一证书关联 。 有关 TLS 的详细信息,请参阅了解加密支持。