网络层面优化:DNS解析、连接数、HTTP/2与CDN加速

做接口优化,很多人一上来就改代码、调数据库。但我个人的经验是,先看看网络层面。很多时候,慢的根本不是你的代码,而是数据在网络上绕了一大圈。

这一章,我们聊四个最实用的网络优化手段。它们立竿见影。你想想看,一个接口请求,大部分时间都花在哪里?不就是DNS查询、建立连接、传输数据这几步嘛。

网络层面优化四步走 用户请求 DNS 解析 优化:预解析 / 缓存 / HTTPDNS 建立连接 优化:减少连接 / 长连接 / 复用 传输协议 优化:升级到 HTTP/2 CDN 加速分发 优化:静态资源 / 动态加速 💡 核心逻辑 从用户请求到服务器响应, 每一个网络环节都可能 成为瓶颈。逐个击破, 效果最可控。

1. DNS解析优化:别让域名查询拖慢第一秒

一个请求过来,第一步是DNS解析。说白了,就是把域名翻译成IP地址。如果这一步慢了,后续再快也没用。

为什么会慢? 本地DNS缓存没命中,得去上级DNS服务器递归查询。跨运营商、跨地区,甚至有时候会丢包重试。我在项目中遇到过,某个接口偶尔超时,查了半天是DNS解析花了800多毫秒。

我个人习惯,从这几个角度下手:

优化手段 原理 适用场景 延迟降低效果
DNS预解析 页面加载时提前解析后续域名 Web页面、首屏加载 减少100-200ms
DNS缓存 延长TTL,利用本地缓存 所有场景 减少80%的DNS查询
HTTPDNS 绕过Local DNS,直连权威服务器 移动端App、全局负载均衡 显著提升稳定性

实践小贴士

在HTML的head里加上 <link rel="dns-prefetch" href="//api.example.com"> 就行。浏览器会尽早开始解析这个域名。

更激进一点,用 preconnect:<link rel="preconnect" href="//api.example.com">。它不仅做DNS解析,还提前完成TCP握手和TLS协商。

<!-- 示例:DNS预解析配置 -->
<head>
  <meta charset="UTF-8">
  <title>我的页面</title>
  <!-- 提前解析静态资源域名 -->
  <link rel="dns-prefetch" href="//cdn.example.com">
  <link rel="dns-prefetch" href="//api.example.com">
  <!-- 更进一步的预连接 -->
  <link rel="preconnect" href="//api.example.com">
</head>

注意避坑

我曾经踩过一个坑:把十几个域名都配了DNS预解析。结果浏览器真的去解析了,反而占用了CPU和网络资源,首屏加载更慢了。嗯,这里要注意——只预解析关键的、马上就要用的域名。一般不超过3个。

2. 减少连接数:TCP握手和TLS握手的开销

HTTP/1.1时代,每个请求基本都要创建新连接。三次握手、四次挥手,加上TLS的证书验证、密钥交换,一次连接下来轻轻松松几百毫秒。

连接开销到底有多大? 我做个测试你就明白了:

连接阶段 RTT消耗 大约耗时(RTT=50ms)
TCP三次握手 1.5 RTT 75ms
TLS 1.3握手 1 RTT 50ms
HTTP请求/响应 1 RTT 50ms
总计 3.5 RTT 175ms

这只是创建一个新连接。如果你的接口要连续请求5个资源,按HTTP/1.1的串行方式,时间就是5倍的连接开销。你算算,光握手就快1秒了。

怎么优化? 我建议:

  • 启用Keep-Alive:复用TCP连接。Nginx和大多数Web服务器默认都开,但超时时间别设太短。我一般设75秒。
  • 域名收敛:把静态资源和API放在同一个域名下,减少跨域连接数。或者用少数几个域名。HTTP/1.1对同一域名有并发限制(通常是6个),域名太多反而增加连接开销。
  • 资源合并:CSS Sprite、JS打包、内联小图片。减少请求数,就是减少连接数。

核心观点

连接数每减少一个,就省掉至少 1.5 个 RTT 的时间。对于移动端、弱网环境,这节省的是实实在在的秒级体验。

3. 使用HTTP/2:多路复用解决队头阻塞

HTTP/1.1有个老大难问题:队头阻塞。什么意思?就是一个连接上只能同时处理一个请求。前一个请求没响应,后面的就得排队等着。哪怕服务器已经准备好了,也得等前面的车开走。

HTTP/2的核心改进就是多路复用。一个连接上可以同时跑多个请求和响应,互相不干扰。你发你的,我收我的,数据流交织在一起传输。

我记得有一次优化一个图片列表接口,用HTTP/1.1时,10张图片要开6个连接,但还是因为队头阻塞,总耗时2.8秒。换成HTTP/2后,全用1个连接,多路复用,总耗时一下子降到0.9秒。效果就是这么明显。

特性 HTTP/1.1 HTTP/2
多路复用 不支持 支持,一一连接并发
队头阻塞 存在 基本解决
头部压缩 明文,无压缩 HPACK压缩
服务器推送 不支持 支持
连接数 通常6+个 1个足够

实践要点

升级到HTTP/2很简单——你的Web服务器(Nginx、Apache、Caddy)都支持,配置一下证书(HTTPS)和协议启用就行。连代码都不需要改。

但要注意:HTTP/2需要HTTPS。另外,如果你还在用域名分片(把资源分散到不同域名)来提升HTTP/1.1并发,现在可以改回来了。HTTP/2不需要这个,反而会增加连接数。

# Nginx 启用 HTTP/2
server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://backend;
    }
}

4. CDN加速:把内容搬到离用户最近的地方

网络延迟的根本原因,就是光速有限。数据在光纤里跑,从北京到上海大约20ms,到纽约大约150ms。物理距离决定了延迟的下限。

CDN怎么解决的?在全球部署边缘节点。你的静态资源(JS、CSS、图片、甚至API响应)被缓存到离用户最近的节点上。用户请求直接命中边缘节点,不再需要绕回源站。

我个人建议,只要你的用户分布在多个地区,CDN就是必备品。它不只能缓存静态资源,现在很多CDN还支持动态加速:通过智能路由、TCP优化、私有协议,让动态接口的延迟也降低30%-50%。

CDN优化要点:

  • 缓存策略:设置合理的缓存过期时间(Cache-Control、Expires)。对于不常变动的资源,缓存时间可以设长一点(比如30天)。版本号管理更新。
  • 预热:大版本上线前,主动把资源推送到CDN节点。避免大量用户首次访问时回源,造成源站压力骤增。
  • 动态加速:对于API接口,开启CDN的动态加速功能。它通过优化的路由和连接管理,减少网络抖动和丢包。
  • 边缘计算:部分CDN支持在边缘节点运行轻量代码。你可以把简单的API聚合、格式转换、鉴权放到边缘做,进一步减少回源。

关键指标

CDN的命中率是核心监控指标。一般静态资源命中率应达到 95% 以上。低于90%说明缓存策略不完善,需要检查缓存键、过期时间、或者有没有意外绕过了缓存。

一口吃不成胖子,网络优化也是。我个人习惯是:先上CDN和HTTP/2,这俩改动最小、收益最大。如果还有问题,再回来优化DNS和连接数。一步一步来,效果看得见。