DNS全局负载均衡(GSLB):原理与实践
说实话,刚开始接触多活架构那会儿,我一听“GSLB”三个字母就觉得特别高大上。后来踩了几个坑才明白——GSLB说白了就是DNS的“智能进化版”。它不再是傻傻地返回一个IP,而是根据你定好的策略,给用户“最合适”的那个入口。
我习惯把GSLB放在路由策略的最外层。你想想看,用户的第一个落点在哪?DNS啊。如果第一跳就选错了数据中心,后面再怎么做故障转移都慢半拍。所以这一章,我就把GSLB从原理到实战掰开揉碎讲清楚。
为什么需要GSLB?
传统DNS解析有个大问题:它不管后端是否活着。一台服务器挂了,用户依然会被解析到那个IP,然后干等超时。我在项目中遇到过不止一次:上海数据中心宕机了40分钟,第三方DNS缓存还没刷新,江苏用户还在拼命连那个挂掉的节点。老板急了,我也急了。从那之后,我深切体会到——
没有健康检查的DNS,就是盲人送快递。
GSLB要解决三个核心问题:
- 多数据中心之间的流量调度——谁来接客?
- 自动故障转移——挂了怎么办?
- 就近接入——用户离谁近就找谁。
GSLB的工作原理
我习惯把它拆成四步走:
- 用户发起DNS查询——比如请求
www.yourapp.com。 - 本地DNS转发——最终落到GSLB专用的权威DNS服务器上。
- GSLB决策引擎——根据健康检查结果、地理位置、当前负载等,算出最佳IP。
- 返回IP并缓存——用户拿到IP后直连对应的数据中心。
你看,核心就藏在第三步。我自己的经验是:GSLB决策必须快,而且要跟后端健康检查实时联动。我曾经见过某家厂商的GSLB,健康检查周期设成60秒,结果故障后整整一分钟还在给用户发故障IP。嗯,这个坑得提前避开。
重要:GSLB的TTL不要设太长。我习惯把TTL控制在60~120秒。太长的话,故障切换后用户继续用旧缓存;太短的话,DNS查询压力激增。两难,但秒级TTL是主流。
健康检查:GSLB的命脉
没有健康检查的GSLB就是空中楼阁。基于我的实践,健康检查至少要覆盖三个层面:
- ICMP Ping——机器活着吗?(最基础)
- 端口探测——比如HTTP 80端口通不通。
- 业务探针——模拟一次用户请求,看接口正确返回。
我推荐组合使用。有一次我单靠端口探测,结果WEB服务正常但后端数据库挂了,GSLB照样返回“健康”状态,用户点进去还是报错。后来我用业务探针,模拟一次登录请求,才真正把“假活”揪出来。
小技巧:健康检查的探测源最好分布在多个地域,避免单一探测点误判。我自己会至少放两个探针,一个在北京,一个在广州,交叉验证。
路由策略对比
GSLB支持多种调度策略,我把常用的几种放在一个表里,这样你一眼就能看清差异。
| 策略 | 原理 | 适用场景 | 我的踩坑点 |
|---|---|---|---|
| 轮询(Round Robin) | 按顺序返回不同数据中心的IP | 各中心能力均等 | 没考虑真实负载,容易导致个别节点被打爆 |
| 地理就近(Geo) | 根据用户IP所属区域返回最近节点 | 用户体验优先 | 曾因GeoIP数据库老旧,把上海用户调度到了重庆 |
| 响应时间 | 实时探测各节点响应,返回最快的 | 追求性能 | 探测开销大,且容易被瞬间抖动误导 |
| 权重(Weight) | 按人工设定的比例分配流量 | 灰度发布或硬件差异 | 权重一设错,某个中心直接跑满 |
实际生产里,我往往不会只用一种。比如我会把“地理就近”作为主策略,再叠加一个“响应时间”兜底——如果最近节点响应太慢,自动切到次优节点。这个组合我跑了大半年,效果不错。
一个典型的GSLB流程(SVG图)
下面这张图梳理了从用户输入URL到最终返回IP的全流程。自己画完才发现,中间每一步都有可能出幺蛾子。
代码示例:用BIND 9实现简单GSLB
我在实验环境用过BIND 9的views配合加权轮询。核心思路是:给不同客户端区域返回不同的A记录。下面是个简化配置,我摘几句关键的:
// named.conf 的 GSLB 区域片段
zone "example.com" {
type master;
file "example.com.zone";
};
// example.com.zone 文件
$TTL 60
@ IN SOA ns1.example.com. admin.example.com. (
20250301 ; serial
3600 ; refresh
900 ; retry
864000 ; expire
60 ; minimum
)
; 华南地区 -> 优先广州数据中心
view "south" {
match-clients { 14.0.0.0/8; 58.0.0.0/8; };
zone "example.com" {
type master;
file "example.com.south.zone";
};
};
; 华东地区 -> 上海数据中心
view "east" {
match-clients { 101.0.0.0/8; 115.0.0.0/8; };
zone "example.com" {
type master;
file "example.com.east.zone";
};
};
你看,这样就可以做到按地理区域返回不同IP。但注意:GSLB的配置一定要跟健康检查联动。我当初只是手动配置了静态view,结果上海挂了,华南用户依然傻等。后来我加了个外部脚本,一旦探测到某节点故障,自动切换该view指向备用IP。这才是真正的GSLB。
避坑指南
- TTL陷阱: 我曾经把TTL设成3600秒,故障切换后用户一个小时都还走老路。现在低于120秒我都不舒服。
- 健康检查误报: 只做ping不够。一定带上业务探针。
- GeoIP精度: 别迷信GeoIP库。我遇到过一个运营商IP被识别成另一个省份,导致调度混乱。定期更新库,或加上人工白名单。
- 权重计算: 权重总和不要超过100,也不要太接近(比如99:1),否则微小的健康变化会导致雪崩。
GSLB是多活路由的第一道闸门。它的配置看似简单,但坑都在细节里。我每次新项目上线前,都会做一次完整的“GSLB演练”:拔掉一条链路,看DNS切换耗时多少,用户侧感知如何。嗯,建议你也试试。