前言

我敢说这绝对是最适合正在纠结要不要给博客网址加上 www 的你阅读的文章,因为我已经替你纠结过了。让我们以一个从 example.com 迁移到 www.example.com 的具体案例来为你解释前者与后者在 DNS 性能、CDN 覆盖和业务管理上的区别。

裸域:DNS 解析的天生逆境

以前我用 Netlify 托管站点的时候,主站的裸域名 pil0txia.com 默认 CNAME 解析在 Netlify 的负载均衡器上,请求会先访问 apex-loadbalancer.netlify.com,然后返回一个相对较近的 CDN 节点的 IP 地址。现在看来其实是绕了远路的,这也是后来 Netlify 文档 中补充 这意味着裸域名不能利用全球CDN上的直接DNS路由,我们建议在使用外部DNS时为你的主域使用一个子域 的原因。

而且,按照 RFC 规范,@ 解析不支持 CNAME 记录,否则会和 MX 记录冲突,导致域名邮箱收不到邮件。但我以前用了很久这样的配置,邮箱也没有丢件,是因为 DNSPod 对 @ 解析的 CNAME 记录默认启用了 CNAME 加速,类似于 Cloudflare 使用的 CNAME Flattening 技术,由 DNSPod 服务器代替用户递归解析并直接返回 A 记录,避免了冲突。

裸域:CDN 覆盖的如获新生

不过 DNSPod 不像 Cloudflare 有很多数据中心、可以解析出离用户最近的 CDN 节点,DNSPod 免费版只有上海、南京两个区域的 DNS 集群,很有可能无法做到分地区分运营商解析,使 CDN 的优势损失。后来我为了用国内的 CDN 节点,专门跟客服求证了这一点:

Q:

DNSPod 给在腾讯云购买的域名解析 DNS 时,能否支持 edns_client_subnet (ECS) 协议,也就是说,在没有手动配置线路的情况下,自动根据用户的位置,返回更近的解析?

良好支持就是细分地域解析(CDN 的节点粒度),反之就是没那么细(DNS 节点的粒度),甚至产生偏差(因为免费版和第一个付费版的境内节点都在上海和南京)。

A:

CDN 也是托管在我们 DNSPod,我让后台确认下,是否有加速,是否影响解析精度。

您好,经后台确认,腾讯云 CDN 的域名是用的 DNSPod 解析,并且要开启 CNAME 加速。如果是 DNSPod 解析就支持开启 CNAME 加速,对 CDN 本身没有影响,还是根据客户端的 localdns 请求过来做返回。

加速时间是,不用客户端 DNS 再次请求到 DNSPod,一次请求就返回了 IP。不是 DNSPod 解析 的 CDN 就不支持 CNAME 加速。

也就是说,由 DNSPod 负责解析的 CDN(如腾讯云和多吉云),DNSPod 储存了 CDN 不同节点的地理位置与线路,可以根据用户透传过来的 IP 位置做就近解析。

但如果不是由 DNSPod 负责解析的 CDN,应该使用传统方式,依靠 CDN 解析的域名来实现这一点。如果此时开启 CNAME 加速,就会由 DNSPod 错误地代替用户查询了并不是最优的 IP 地址。

www:是遗老还是经典

出生在互联网时代的 Blogger 们:在 WWW 还在被称作万维网的时候,作为一个 IT 管理员,你的网络系统就是你的域,比如 example.com。域的下面是主机,每个联网的设备都可以算作一个主机。

在你的域内,为网络页面提供服务的主机通常被加上 “www” 前缀,它的主机名也就是 www.example.com。在互联网早期阶段,还没有虚拟主机和托管平台这回事。 所有网页服务器的主机名都要指向一个 IP 地址,只有在裸域需要迁移时才指向另一个网址。

互联网普及开后,一些管理员开始把裸域名指向和网页服务器主机同样的 IP 地址,访客只需在浏览器中输入 example.com 即可访问,而不用输入完整的 www.example.com。我喜欢这样,这很简洁,这也是我一开始采用 Netlify 默认设置的原因。

example.comwww.example.com 对搜索引擎而言意味着两个相同的网站。为了搜索引擎优化 (Search Engine Optimization,SEO),必须选择一个规范的名称,而且另一个也要使用 HTTP 301 响应码来指向这个规范的主机名。

对 SEO 而言,选哪个都一样。但是从业务的实践上来说,就有很大区别了。首先,我们上面讲了 DNS 的性能问题和 CDN 的覆盖问题,这让我考证了好一段时间,因为我一开始并不信任没有被写在规范中的基础设施新技术。那么我们现在知道了,至少在 Cloudflare 或腾讯云这两家厂商的封闭体系中,我们可以享受到给裸域使用 CDN 加速的全部优势,但谁知道我会不会有一天转向别的厂商呢?

此外,虽然我们都知道饼干 (cookie) 是用来吃的,但它如果被设置在 example.com 裸域上,它的 domain 属性(也就是作用域)将会使它被发送到所有的子域名上,包括 mail.example.compay.example.com 等你并不想看见它的地方。为了避免这种情况,开发时必须不显式地指定 domain,浏览器就只会生成一个针对当前域名的 cookie,不包含子域名。

如果我正在为你的网站进行安全审计,目前只有 mail.example.com 的权限,而你把 CMS 部署在了 example.com 上,那我一定会试着读取一下 CMS 给你的浏览器发送的 cookie,说不定就能以你的名义登录 CMS 的管理后台。

我为什么要迁移到 www

说真的,如果你只是一个人写写给自己看的文章,随你的喜好吧。也许是我看了两年的 pil0txia.com 有点腻了,也可能是我在电脑前忙活了一整天感到了厌烦,反正我睡了一觉第二天醒来后就觉得 pil0txia 的字母 p 的下摆太长了,也许用 www.pil0txia.com 来平衡一下左侧的重量也蛮好的。

迁移之后不能忘记的事

作为一个跟静态页面和前端打交道的 Blogger,回到 WordPress 那种相对高昂的运营支出仿佛是一种背叛。但当我完成 ICP 备案后寻寻觅觅都找不到一个支持 301 跳转的服务商时,我忍不住地想要不要掏出自己 Azure 的云主机。是的,我知道想要把 @ 重定向到 www 只需要 302 跳转就行了,这用任何一家的 URL 重写都可以做到。但是看着谷歌搜索结果里我的索引混杂着 https://pil0txia.comhttps://www.pil0txia.com,着实有一种在逛 V2EX 的感觉。

301 跳转会让谷歌知道我的站点地址发生了更改,然后慢慢地从搜索结果中把旧地址的流量转移到新地址上,并最终完全剔除旧的地址。无论是域名迁移还是站点迁移,这都是对 SEO 最友好的方式。然而在整个备案和迁移的过程中,唯一与我的预想不符的是,DNSPod 的显性 URL 转发并不支持 HTTPS 地址,因为它的转发服务器上没有我的 SSL 证书,也不支持设置。

还好我还记得七牛云的 OSS 对象存储可以 301 跳转。对于只有 CDN 的 HTTP 流量计入免费额度的七牛云来说,由存储桶直接吞吐 HTTPS 流量是会计费的,但这通常达不到计费的最小精度 (0.01)。事实上,四年来,我体验了所有云服务厂商几乎所有的产品,还从来没有在基础设施上花过一分钱。

附言

最后,我为什么要用 “裸域” 这么别扭的名字?因为它是英译中后的名词中唯一没有产生误解的。

让我澄清一下,顶级域或根域名 (Top-level Domain,TLD/root domain) 都指的是类似于.com 的 “后缀”,也被称为一级域名;example.com 在英文中被称为 apex domainbare domain,但前者直译过来的 “顶域” 实在太容易与 TLD 混淆了,只有 “裸域” 还能直接称呼。

曾经口口相传的 “二级域名 (Second Level Domain,SLD) ” 也并不是 “子域名 (subdomain) ”,前者等同于裸域,而后者类似于 www.example.com,其实是三级域名。国内云服务厂商的人员培训根本没有做好这一点,往往不知所云。