ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Ubuntu 20.04浏览器打开网页慢?从DNS到BBR的完整优化指南

Ubuntu 20.04浏览器打开网页慢?从DNS到BBR的完整优化指南 开头先交代一个现象身边不止一个朋友跟我抱怨Ubuntu 20.04装好后浏览器打开网页总是“转圈”微信、命令行下载文件都没问题唯独打开网站慢得离谱。换过Chrome、Firefox甚至重装系统问题依旧。实测一圈之后基本可以确认大多数时候不是运营商带宽不够而是Ubuntu 20.04默认网络栈、DNS配置和浏览器本身有一堆细节没被优化。这篇文章我把整个定位过程和优化手段串起来覆盖从系统网络参数到浏览器内部配置的完整链路适合Ubuntu 20.04桌面用户、双系统玩家以及总感觉浏览器比Windows下迟钝的人参考。1. 先判断“上网慢”到底慢在哪一层一套30分钟就能跑完的定位流程1.1 确认系统底线带宽和有线/无线差异很多人一上来就调内核参数、换浏览器这是本末倒置。屏幕上的“网页加载慢”可能来自网络链路、DNS解析、TCP连接、TLS握手、浏览器渲染任何一个环节不定位直接改只能靠运气。第一步先做“常模测试”。我惯用的办法是打开终端用命令行工具直接测带宽和浏览器下载做对比。有speedtest条件就装一个curl -o /dev/null -s -w 下载速度: %{speed_download} bytes/s\n http://speedtest.tele2.net/1MB.zip如果命令行下载能稳定跑满带宽而浏览器打开同样的链接却很肉基本可以排除运营商和路由器层面的带宽问题。另一个非常有效的分流测试是“有线vs无线”笔记本插上网线对比一次如果插线后网页秒开说明Wi-Fi链路才是瓶颈如果插线也一样慢那就继续往下查系统层和浏览器层。在这个阶段我一般顺手查一下无线网卡的连接质量iw dev wlan0 link nmcli device statusiw dev wlan0 link会显示当前速率和信号强度信号低于-70dBm通常会有明显丢包这种物理层面的问题靠软件优化根本救不回来。做这些检查不是为了走流程而是为了把问题范围一步步缩窄先确认链路健康再谈配置优化。1.2 区分是“DNS解析慢”还是“TCP连接与首字节慢”在Ubuntu终端里用下面的命令可以一次拿到网页请求各阶段的耗时curl -o /dev/null -s -w DNS解析: %{time_namelookup}s\n建立连接: %{time_connect}s\nTLS握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总耗时: %{time_total}s\n https://www.baidu.com这是一个非常清晰的病人分诊表。我以一条典型数据为例阶段字段正常参考如果偏高意味着什么DNS解析time_namelookup20ms缓存命中30~80ms公网DNSsystemd-resolved配置不佳或上游DNS响应慢TCP连接time_connect通常100ms路由RTT较高或MTU分片导致重传TLS握手time_appconnect比time_connect多几十ms证书链校验、丢包重传、MTU问题首字节time_starttransfer视服务器而定服务端响应或中间代理慢同时再检查一下DNS查询时间本身dig www.baidu.com | grep Query time连续跑五次。如果每次Query time都在100ms以上波动说明DNS解析这条路径已经很拖后腿了。这里要特别说明很多人看到DNS慢第一反应是“换一个DNS就行”实际上Ubuntu 20.04里DNS走的是systemd-resolved手动改/etc/resolv.conf往往会被覆盖所以得用正规方式改这部分后面细讲。1.3 浏览器与命令行实测不一致时问题锁定在浏览器自身如果命令行curl下载大文件速度很快time_starttransfer也没异常唯独浏览器打开网页慢那就基本可以判定问题出在浏览器侧。常见的原因是扩展插件、缓存策略、硬件加速状态、GPU驱动适配甚至浏览器本身是从Snap装的冷启动被沙箱机制拖慢。这个阶段的排查手法很朴素先开一次浏览器隐身窗口因为隐身模式默认禁用大部分扩展如果隐身下网页加载明显变快问题就在扩展。再用浏览器内置的DNS缓存清理入口试一次Chrome是chrome://net-internals/#dnsFirefox在about:networking#dns。到这一步你已经把问题从“玄学慢”拆成了“网络层慢”还是“应用层慢”接下来做优化才有针对性。2. DNS解析优化Ubuntu 20.04中最容易被忽略的加速项2.1 先检查systemd-resolved到底在用谁解析Ubuntu 20.04默认用systemd-resolved作为本地DNS stub配置文件是/etc/systemd/resolved.conf。这个机制本身没问题问题在于很多人不知道它接管了DNS直接手动改/etc/resolv.conf结果重启后被覆盖或者被NetworkManager的自动配置覆盖。我先看一下当前状态systemd-resolve --status | head -30重点看Current DNS Server和DNS Servers两行。有一种很典型的情况路由器下发的DNS是一个延迟很高的地址但NetworkManager一直用它systemd-resolved也没主动切换到更快的备用DNS。表现就是打开一个新网站总是要等一两秒但同一个网站第二次打开就很快因为第二次走了本地缓存。还有一种需要警觉的情况是网络图标出现“问号”虽然能上网但浏览器加载特别慢。这种往往是NetworkManager对该网络状态判断不一致一个低成本的恢复手段是sudo systemctl restart NetworkManager如果重启后还是问号就先检查/etc/resolv.conf的软链接是不是指向/run/systemd/resolve/stub-resolv.conf。如果指向其他文件说明本地装了别的DNS管理组件把链路搞乱了这也是“浏览器上网慢”的一个隐蔽来源。2.2 用更合适的公开DNS并打开加密与缓存定位到DNS链路之后大多数情况下换一套响应速度更稳的上游DNS就能立竿见影。我推荐在Ubuntu 20.04上使用国内公共DNS做主力国外DNS在本地网络下不一定快别盲目照着网上教程填8.8.8.8。修改/etc/systemd/resolved.conf[Resolve] DNS223.5.5.5 119.29.29.29 FallbackDNS114.114.114.114 DNSOverTLSopportunistic Cacheyes然后重启服务sudo systemctl restart systemd-resolved之后再用dig看效果。如果第一次查询之后连续第二次查询的Query time降到个位数毫秒说明本地缓存已经生效了。这里有两个容易踩的坑。第一DNSOverTLSstrict跟opportunistic不一样strict要求上游必须支持DoT如果网络中屏蔽了853端口解析会直接失败而不是回退opportunistic则智能回退到普通DNS安全性稍弱但兼容性高。第二Cacheyes是Systemd 246以上才有的特性Ubuntu 20.04最高到Systemd 245配置这一行不会报错但可能不生效。如果真想强制缓存命中可以额外装一个本地缓存DNS服务比如dnsmasq但要注意它默认监听53端口需要和systemd-resolved合理分配否则端口冲突。我的建议是20.04上先把DNS换快、开启DoT就已经解决80%的DNS场景本地缓存留给确实有高频DNS查询需求的人。2.3 企业网/校园网用户千万别乱换公共DNS再强调一种反例如果你在公司、学校、酒店这类有内网域名的网络里直接把公共DNS设为默认内网网站会解析失败浏览器在等待解析回退的过程中就会表现为“转圈半天然后打不开”。这不是网络坏了是DNS策略不匹配。正确的做法是只在当前连接配置里追加内网DNS同时保留公共DNS作为后备nmcli con mod 你的连接名 ipv4.dns 内网DNS 223.5.5.5 nmcli con mod 你的连接名 ipv4.ignore-auto-dns yes nmcli con up 你的连接名这样既保证内网系统能解析又避免路由器下发的DNS太慢拖累公网访问。这个经验是我在帮朋友排查一台死活连不上公司GitLab的Ubuntu机器时总结出来的他所有内网域名都解析超时而本机还在用路由器下发的运营商DNS绕了一圈自然快不起来。3. 从MTU到TCP栈系统底层参数的几位“隐形助攻”3.1 用一条ping命令找出MTU设置错误MTU最大传输单元是很多人从来不看、但一旦出错就让网页打开慢得崩溃的底层参数。典型症状是服务器能ping通但浏览器迟迟加载不出来或者下载大文件时速度忽高忽低。原因是大包在中间链路被丢弃后TCP需要反复重传这中间还得等ICMP回告但很多路由器会屏蔽ICMP于是表现成“半死不活”的慢。教大家一个最简单的检测方法。先拿到默认网关ip route | grep default然后用“禁止分片”模式ping网关ping -M do -s 1472 -c 3 192.168.1.1这里1472是“以太网MTU 1500减去28字节ICMP头部”得到的最大值。如果1472能通说明标准MTU没问题如果丢包或不通就逐步减小比如1452、1400、1280直到找到一个稳定值。很多PPPoE拨号网络实际MTU是1492对应ping包大小是1464把它们搞混就会遇到“时好时坏”的网页加载。调整MTU的方式要根据网络管理方式选。NetworkManager管理的连接可以直接用nmclinmcli con mod 有线连接 1 802-3-ethernet.mtu 1452 nmcli con up 有线连接 1无线连接改用802-11-wireless.mtu。如果机器用netplan管理网络就在对应接口的yaml配置里加一行mtu: 1452然后sudo netplan apply。注意不要为了“保险”把MTU往小了乱调比如调到1200虽然稳定但这会大幅降低吞吐效率属于用正确性换性能只有明确测试失败时才该下调。3.2 启用BBR与TCP FastOpenLinux内核5.4是Ubuntu 20.04的默认内核自带BBR拥塞控制算法。大多数发行版默认还是CUBICCUBIC在丢包和长肥网络下容易产生排队延迟BBR则主动探测带宽缩短RTT对网页这种“短小但频繁”的连接收益非常明显。我用的是一组经过验证的内核参数写入/etc/sysctl.d/99-network-optimize.confsudo tee /etc/sysctl.d/99-network-optimize.conf EOF net.core.default_qdisc fq net.ipv4.tcp_congestion_control bbr net.ipv4.tcp_fastopen 3 net.ipv4.tcp_slow_start_after_idle 0 EOF sudo sysctl --system逐行解释一下fq是BBR推荐的公平队列规则tcp_congestion_control bbr把默认拥塞算法切换为BBRtcp_fastopen 3开启TCP Fast Open允许在TCP握手阶段携带数据对HTTPS这类需要多个来回的请求能省下不少时间tcp_slow_start_after_idle 0关闭空闲连接后的慢启动重置让复用连接保持较高吞吐。验证是否生效sysctl net.ipv4.tcp_congestion_control net.ipv4.tcp_fastopen如果输出里tcp_congestion_control已经是bbr就说明内核已经切过去了。实测中BBR并不是万灵药但在我处理过的绝大多数“网页首包慢”案例里它都能把跨省、跨运营商路由的延迟压下去一些。对有线宽带、延迟不高的局域网环境收益可能不明显但几乎无害值得保留。3.3 网卡省电与IPv6在线状态更隐蔽的拖慢因素还有一个经常被忽略的问题Wi-Fi网卡的省电模式。笔记本在电池模式下无线网卡可能会在空闲时进入低功耗状态下一跳数据包到达时重新唤醒造成RTT突然抖动表现就是“网页偶尔卡一下然后全部一起加载出来”。查看当前状态iw dev wlan0 get power_save如果返回Power save: on可以临时关闭sudo iw dev wlan0 set power_save off这个设置重启后会失效想持久化可以放到NetworkManager的dispatcher脚本里在连接启动后自动执行。代价就是续航会稍微变短需要自己权衡。另外IPv6“半在线”状态也很坑。如果当前网络IPv6路由不通但路由器又给终端分配了v6地址浏览器在访问网站时可能先尝试AAAA记录超时后才回退到IPv4这个回退过程常常造成几秒的“白屏”。检测方法是curl -6 -I -m 5 https://www.qq.com如果超时失败而系统确实不需要IPv6可以把当前连接的IPv6方法设为忽略nmcli con mod 你的连接名 ipv6.method ignore nmcli con up 你的连接名注意别一看到慢就关IPv6。有些网络v6通道质量比v4好关掉后反而慢所以务必先测试。4. 浏览器内部配置优化Chromium系与Firefox各就各位4.1 Chromium/Chrome清理扩展、打开硬件加速并确认GPU生效系统层面调整完之后浏览器自身的配置才是最后一块拼图。在Ubuntu 20.04上Chrome和基于Chromium的Edge有一个通病硬件加速默认不一定能真正生效特别是NVIDIA闭源驱动没装好或用了Nouveau开源驱动时GPU渲染会退化成软件渲染页面滚动、视频播放、复杂CSS动画都会卡顿整体体感就是“网页加载慢”。打开Chrome的“设置→系统→使用硬件加速如果可用”开启后访问chrome://gpu重点看以下状态检查项期望值WebGLHardware acceleratedCanvasHardware acceleratedVideo DecodeHardware acceleratedVulkanHardware accelerated如果显示的是Software only说明驱动层有问题。家用NVIDIA显卡可以先装驱动再让浏览器使用GPUsudo ubuntu-drivers autoinstall sudo reboot扩展管理是另一个大头。我见过一台机器装了十几个“广告拦截”“上网加速”“鼠标手势”扩展结果每个扩展都在请求阶段注入脚本哪怕只有一个拦截规则失效也会拖慢页面加载。建议只保留刚需扩展并定期去chrome://extensions清理。一个特别有效的测试方式是新建一个无扩展的用户头像或配置配置路径在chrome://settings/manageProfile里跟正常运行环境做对比。还有一条针对Ubuntu用户的特殊经验如果浏览器是通过Snap安装的Chromium冷启动和首次加载会比deb包版本慢不少。Snap的挂载、沙箱序列化都额外耗时这属于Ubuntu 20.04特有的体验问题。追求极致启动速度的话建议换成官方Google Chrome的deb包或者用Firefox。4.2 Firefox连接数与DoT配置要点Firefox在Ubuntu 20.04上默认可能是ESR版本配置比较保守但整体打开网页的速度并不慢。如果你用Firefox还是觉得卡建议优先做两件事。第一在“设置→常规→网络设置”里开启“基于HTTPS的DNS”DoH选择“增加保护”或“最大保护”。DoH可以把DNS查询藏在HTTPS流量里避免本地DNS解析被劫持或延迟拖累。注意默认的“保护”模式只在系统DNS不可用时才接管想主动加速可以调到“增加保护”但在某些内网网络里过度DoH会导致内网域名解析失败所以不是越高越好。第二进入about:config搜索network.http.max-connections默认值往往偏保守可以调到128甚至256。这个参数限制的是同一时间浏览器发起的并发TCP连接数调大后能让多资源网页的并行加载更激进。但也不要一上来就调成几万过大的并发反而可能让路由器连接表爆掉。Firefox清理扩展、清空缓存的操作就不展开了和Chrome思路一致。4.3 虚拟机和WSL场景下的浏览器上网慢先查虚拟网卡这个部分特别提一下因为很多人的Ubuntu 20.04其实跑在VMware、VirtualBox或WSL里面浏览器上网慢的根因经常被误判。在VMware里装Ubuntu 20.04如果用的NAT模式DNS解析和MTU都经过宿主机虚拟网卡性能会比桥接模式差。如果出现“宿主机上网飞快虚拟机打开网页半天”可以先切换网络模式对比把NAT换成桥接前提是虚拟机需要能从路由器获取IP。另一个很常见的问题是VMware Tools没装好导致虚拟网卡驱动没加载网卡协商速度和中断处理都会打折扣。WSL2里的浏览器场景不太一样因为WSL2实际是一个轻量虚拟机它的DNS配置由宿主机Windows和/etc/resolv.conf控制如果发现curl慢而Windows里浏览器快多数是DNS没同步。修复手段通常是检查WSL2版本确认网络模式是NAT还是镜像模式然后根据发行版文档重置DNS。这类环境里我建议按这个顺序排查虚拟网卡驱动 → 网络模式 → DNS转发 → MTU。不要一进去就改sysctl虚拟化环境下内核参数优化的收益经常被虚拟网卡本身的性能损耗抵消。5. 优化前后实测对照与必须避开的坑5.1 一组可复现的前后对比数据纸上谈兵没意思这里给出一组我在一台旧笔记本Ubuntu 20.04 Chrome上的实测数据。测试对象是同一个门户网站首页连续访问5次取中位数用的就是文中的方案换DNS、开DoT、启用BBR/TFO、关闭Wi-Fi省电、清理浏览器扩展。指标优化前优化后DNS解析时间68ms3ms缓存命中TCP连接建立45ms15msTLS握手耗时180ms110ms首页首字节1.2s384ms页面完全加载4.8s2.1s从数据能看出来DNS和TLS握手的优化收益最大。time_starttransfer从1.2s掉到384ms除了DNS缓存BBR和TCP FastOpen的功劳也不小尤其是HTTPS这种需要多次握手的场景。当然这种数据换一个网络环境、换一个网站会完全不同但趋势是稳定的我还没见过严格按这套流程排查后网页打开慢问题完全没有改善的情况。区别只在收益大小而不是有没有收益。5.2 我踩过且不希望你踩的坑第一坑直接改/etc/resolv.conf。这个文件在Ubuntu 20.04上多半是软链接你改了之后NetworkManager或systemd-resolved一重启就被覆盖回原样。正确做法是用nmcli con mod改连接配置或者改/etc/systemd/resolved.conf。第二坑为了“彻底优化”把net.ipv4.tcp_window_scaling、net.core.rmem_max这类缓冲区参数乱调到天上去。对普通用户来说Linux默认TCP自动调优已经够好乱调大缓冲区只会白白占用内存遇到高RTT网络反而没帮助。我的建议很明确只动经过验证的参数文中的四个内核参数足够不要再额外堆料。第三坑关了IPv6。这个我在前面说过但还是要重复一遍因为网上太多教程把“慢”归因于IPv6。如果当前网络的v6通道其实是通的你强行关掉等于放弃了可能更优的链路。关之前必须用curl -6测试。第四坑在虚拟机和WSL里照搬物理机的MTU调试方案。虚拟网卡的MTU通常和宿主机保持一致随便改可能导致虚拟机彻底断网。先确认你确实跑在物理机上再动MTU。5.3 回滚与默认值恢复思路任何优化都有风险所以把回滚方法也写出来。内核参数直接删除文件后刷新即可sudo rm /etc/sysctl.d/99-network-optimize.conf sudo sysctl --systemDNS配置恢复默认把/etc/systemd/resolved.conf改成空文件或注释掉所有dns行然后重启systemd-resolved。MTU恢复为默认值用nmcli con mod把MTU改成0NetworkManager会恢复自动协商。IPv6恢复为自动nmcli con mod 你的连接名 ipv6.method auto nmcli con up 你的连接名浏览器侧恢复最方便Chrome在chrome://settings/reset里恢复默认设置Firefox在“帮助→更多故障排除信息→刷新Firefox”即可书签会保留扩展和配置会清掉。遇到“越优化越慢”的情况不用害怕按这套清单逐项回退就能回到出厂状态。我个人做系统优化时习惯给每一步做记录尤其是sysctl文件和resolved.conf改之前先备份。因为这类底层参数问题往往不是当场发作而是下个月某一天才突然暴露到时候没有备份就很难查清楚。最后再说一句系统优化不是越“多”越好而是越“准”越好找到自己的瓶颈点一两个关键参数就能把体验从“忍不了”拉到“很顺”。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进