如何解决 Azure Always On listener 无法访问的问题
本文旨在解决 Always On 无法从 secondary replica 通过 listener 连接集群,时而出现不能访问的常见问题。
Always On 介绍
Always on 是 SQL Server on VM 的架构下最常见的高可用方案。
其基本原理为创建一个至少为 2 台 VM 所组成的 Windows 集群,每台 VM 上安装一台 SQL Server Instance。由其中的一台 SQL instance 作为主节点(primary replica)提供对外读写访问,同时通过日志传输的形式提交到另外一台节点(secondary replica)进行数据同步。
Secondary replica 可以提供只读功能,用于做读写分离或高可用(强烈建议依旧保持备份的习惯)。
备注
在 SQL server 2016 之前的版本,组成 Windows cluster 还需要一台 Domain controller(DC)。 搭建步骤:在 Azure VM 中手动配置 Always On 可用性组。
在 Azure 中搭建 Always On 的过程并不复杂,但是经常有客户会遇到搭建 Always On 之后无法使用 App 连接的自动故障转移功能。
Always on 的自动故障转移功能基于 Always on Listener。Listener 会被注册为一个 windows cluster 中的 resource,类似于 VIP 概念;在集群发生故障转移时 listener 会被漂移到新 primary 的 VM 中。对于客户端来说,只需要访问 Listner 的 IP 地址就可以保证永远连接到当前的 primary 数据库上。
在传统的 IDC 环境中,Always On 会自动将 Listener 所属的虚拟 IP 地址与网卡物理地址注册到路由表中,所以无论任何节点都可以通过 Listener 找到 primary 所在的服务器地址并建立链接。
在 Azure 环境下,该地址无法被注册,所以我们需要通过增加一个 Load Balancer 的方式来为 Listener 的访问请求进行转发。
参考示例脚本:使用 PowerShell 将 IP 地址添加到现有负载均衡器
该脚本非常重要,会在 primary 节点上创建一个始终监听在 <n.n.n.n>
端口上的监听,并会随着 primary 切换而自动转移到新的 primary VM 上。本示例中使用 59999
。
在配置好了 listener 之后可能会遇到以下几个常见问题:
- 在 primary 节点上可以通过 listener IP 访问集群,但在 secondary 上无法访问 listener IP,只能通过提供 primary 服务器名或 IP 的方式来进行连接。
- 在 secondary 上有时候可以访问 listener IP 有时候就不行,随机出现。
如果遇到上述问题,我们可以通过以下几个步骤进行排错:
开始=>运行=>cmd 输入
netstat -a
检查,是否59999
监听端口已经在 primary 节点中存在。检查 Azure 门户中 Load Balancer 上的 probe(探测器),探测的端口是否为
59999
或者是之前在 PowerShell 中创建的<nnnnn>
端口。[int]$ProbePort = "<nnnnn>" # Probe port
经常会有客户错误配置为
1433
端口,对于 LB 来说,1433
在 primary 和 secondary 都为存活状态,所以会随机的分配 request 给任何一台节点,可能是 primary,可能是 secondary。由于 Always On 必须要先访问 primary,所以如果该请求发给了 secondary 就会得不到响应。
Azure 门户中 Load Balancer 的 front IP 是否与 Windows cluster resource 中的 listener 的 IP 完全一致。
负载均衡规则中的 probe 是否配置。
如果以上步骤全部配置正确,通常就可以正常的使用 Always On 了。