修改域名记录别忘了TTL

小菜在一家互联网公司工作,负责后台开发。他们公司有一个 APP ,运营需要分析用户操作体验。为此,研发团队准备在 APP 中埋点,以便上报数据。而小菜需要提供一个后端服务,用来接收 APP 上报的数据。

小菜开发好数据接收服务后,申请了一个域名,让 APP 团队通过域名提交数据。这样一来,小菜以后可以灵活地调整后端服务,随意扩容、缩容,甚至是迁移,完全不用 APP 团队配合。

假设小菜后来将数据接收服务迁到新的服务器上,它只需修改域名解析,指向新的服务器即可。APP 完全不用调整,它查询域名时会得到新的地址,并将数据提交到新的服务器:

不过,小菜也踩过坑:有一次他将服务迁走后,就将旧服务器停掉;结果还是有很多用户的 APP 将数据提交到旧服务器,导致数据丢失;看上去这些 APP 还是会查询到域名的旧记录。

为什么会出现这种现象呢?

这时,经验丰富的程序员应该很容易就能联想到 缓存 。DNS 记录是不是也会被缓存呢?

的确如此,我们前面介绍过的 DNS 缓存服务器 就是专门干这个事的。想要深入研究 DNS 缓存,我们需要先重温一下报文中的 TTL 字段。TTL 我们并不陌生,它表示 存活时间time to live )。

DNS 资源记录中有一个 TTL 字段,表示记录的有效期,单位是秒。这意味着,在有效期内,客户端和中间的缓存服务器都可以将结果缓存起来,不再重复查询。

假设小菜的域名是 some.domain.com ,记录有效期为 10 分钟。这样的话,DNS 缓存服务器可以将查询结果缓存 10 分钟。那么,很有可能会出现这样的情况:

小菜迁移好后端服务后,调整域名 some.domain.com 记录,指向新的服务器。域名调整在权威服务器上可以立即生效,但对 DNS 缓存服务器来说就不一定了。

假设有一台 DNS 缓存服务器,在小菜调整域名前刚好查询了权威服务器。权威服务器向它返回了旧的记录,告诉它 TTL 为 10分钟。DNS 就会将这个结果缓存起来,等有效期过后才会重新查询。

当 APP 向 DNS 缓存服务器查询域名 some.domain.com 时,缓存服务器将缓存的旧记录返回给 APP 。因此,APP 将埋点采集的数据,提交到旧的服务器上去,而旧服务器已经被小菜关掉!这就发生了故障!

理论上,调整域名记录后,在 TTL 时间内,DNS 缓存服务器都有可能仍缓存旧记录。经过 TTL 时间后,按理缓存服务器不可能还有旧记录。然而,由于时间差和系统实现差异等客观因素,这种情况仍有可能零星出现。

那么,域名记录该如何调整,才能避免跟小菜一样踩坑呢?

域名记录调整后,网络中的 DNS 缓存服务器仍可能缓存旧记录,最长可持续 TTL 时长。这时观察新旧服务的流量,可以发现旧服务流量呈线性下降,最终降为零;而新服务流量呈线性上升,最终达到正常流量。

因此,问题解决起来也很简单,就一个字:等。域名调整之后,新旧服务需要并行运行一段时间。旧服务必须等到流量降为零之后,才能停机。

另外,有些基础服务极少会调整,所以域名记录 TTL 可能设置得很长,比如:259200 秒( 3天 )。这类服务如果迁移,理论上旧服务仍需并行运行 3 天。这么长的时间窗口,需要耐心等待。

如果迁移后不想久等,可以提前将 TTL 临时改小,比如改成:600 秒( 10分钟 )。假设记录原 TTL 是 3 天,理论上需要提前至少 3 天进行调整。TTL 改小 3 天后,即可开始迁移服务,并调整域名指向。如此一来,旧服务仅需并行运行 10 分钟即可。

  1. T-3 日,将 TTL 改小,由 3 天改成 10 分钟;
  2. T 日,迁移服务,新旧服务并行运行;
  3. 等待 10 分钟左右,旧服务流量降为零,即可停机;
  4. 迁移完毕后,将 TTL 改回去;

说了这么多,无非想告诉大家,调整域名记录时必须注意以下几点:

  • 域名记录支持 TTL 有效期,DNS 缓存服务器可能会缓存旧记录;
  • 服务迁移后,旧服务不能立即下线,必须等 DNS 缓存服务器中的旧记录逐渐失效;
  • 如果迁移过程不想被拉的很长,可以提前将域名 TTL 改小;

小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注: