ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux DNS配置完全指南:从resolv.conf到systemd-resolved的坑与解法

Linux DNS配置完全指南:从resolv.conf到systemd-resolved的坑与解法 记得刚转做运维那阵子最怕听到的一句话就是“上不了网了”。排查了一圈网卡是up的IP也ping得通最后发现是DNS配置残了。那时候我才真正意识到Linux系统配置DNS这件事看着简单坑一点都不少。后来在几百台服务器、各种发行版上反复折腾过之后我把和DNS配置相关的经验全部整理成了这套打法。这篇文章里没有什么高深理论全部是我实际动手验证过的命令、配置文件和排查思路适合刚入门Linux的选手也适合被DNS问题折磨过的运维老哥。先声明一下这里讲的是“配置DNS”这个动作背后的完整链路不只是改一行地址那么简单。1. 配置DNS前必须搞懂的解析全链路1.1 从一次域名解析请求说起很多人以为DNS配置就是把 /etc/resolv.conf 里的 nameserver 改一改其实这只是最后一步。在Linux系统里一个域名解析请求要经过好几层理解不了这些层次遇到问题就只能瞎猜。拿我在Ubuntu 22.04上的实测经历来说输入ping baidu.com之后请求首先会被应用层交给 glibc 的解析器也就是 getaddrinfo 函数。这个解析器会按照 nsswitch.conf 文件里定义的顺序去查找。默认情况下它先看 /etc/hosts如果里面没有对应记录才会去查 /etc/resolv.conf 里配置的DNS服务器。如果系统里装了 systemd-resolved这个顺序还会再变因为 /etc/resolv.conf 通常是指向 systemd-resolved 生成文件的符号链接。这套链路里最容易忽略的就是 nsswitch.conf。我见过很多人在 /etc/resolv.conf 里配了正确的nameserver但解析还是走 hosts 文件里的旧记录那就是因为 nsswitch.conf 里 hosts 那行写成了hosts: files根本没带dns。正确写法应该是hosts: files dns意思是先查文件再查DNS。另外解析时还有一个超时和重试的机制。glibc 解析器默认的 timeout 是5秒attempts 是2次。如果第一个nameserver没响应要等5秒才切换到第二个这个时间在实际生产环境里会让服务出现明显的卡顿。所以不是配了越多DNS服务器越好配置不当反而会拖慢所有解析请求。1.2 系统里到底哪些文件在管DNS在Linux里管DNS的文件和目录说多不多但每个都有自己的职责范围。我把它们按“用户态配置”和“系统态策略”分两类。用户态配置主要指这三个/etc/hosts静态解析表优先级最高适合内网主机名映射。/etc/resolv.conf配置nameserver、search域、options参数。这是客户端DNS配置的主战场。/etc/nsswitch.conf规定了解析的查找顺序。系统态策略则和具体的网络管理栈有关/etc/NetworkManager/NetworkManager.conf 以及 /etc/NetworkManager/system-connections/ 下的连接配置文件NetworkManager接管DNS时真正生效的是这里的设置。/etc/systemd/resolved.confsystemd-resolved 这个服务的配置控制它监听的DNS、DNSSEC模式、缓存策略。/run/systemd/resolve/stub-resolv.confsystemd-resolved 运行时的实际看到配置当 /etc/resolv.conf 是符号链接时你看到的其实是这个文件。这里有个容易搞混的地方。很多教程说“修改 /etc/resolv.conf 就行”但如果你用的是带图形界面的Ubuntu桌面版NetworkManager 会在你重启网络服务的时候把 /etc/resolv.conf 恢复成它自己管理的样子。也就是说你手动改的内容会被覆盖。这种情况下正确做法是修改NetworkManager的配置文件或者用nmcli命令去设置DNS。搞清楚这些文件之间的优先级和覆盖关系比记住某个命令重要得多。后面我遇到的绝大多数据DNS问题都是因为没弄明白到底哪个服务在管理这个文件。2. 手动修改DNS的四种姿势和适用场景2.1 最直接的临时修改改 /etc/resolv.conf先说最直观的办法。在大多数传统发行版比如CentOS 7、Debian 10、Rocky Linux 9上直接编辑 /etc/resolv.conf把 nameserver 改成你想要的地址执行完立即生效不需要重启任何服务。比如我常用的是这样vi /etc/resolv.conf nameserver 223.5.5.5 nameserver 119.29.29.29改完后用dig www.baidu.com验证如果返回了答案解析就已经生效了。这个方法的优点是简单直接适合临时排查或者测试某个DNS服务器是否可达。但缺点是一旦网络服务重启、DHCP租约更新或者NetworkManager重新接管网络这个文件就会被打回原形。我在实际运维中遇到过一个很典型的现象用户在服务器上手动改了 /etc/resolv.conf当时测试解析正常但第二天早上发现网站访问又全挂了。一看/etc/resolv.conf里面又变回了内网DHCP下发的地址。原因是这台服务器装的是Ubuntu 20.04默认开着 systemd-resolved而 /etc/resolv.conf 是一个指向 /run/systemd/resolve/stub-resolv.conf 的符号链接。你 vi 进去改其实是改了link指向的目标文件一旦systemd-resolved重启它就会把内容重新写回来。所以如果你只想临时修改建议先备份并且要知道这个修改生命周期很短。如果想长期生效就必须往下看。2.2 永久修改针对不同发行版的做法永久修改DNS的正确姿势取决于你用的是哪套网络管理方案。这里我按发行版家族拆开说。RHEL/CentOS/Rocky Linux 系列如果你的网络由 NetworkManager 管理默认就是推荐用 nmclinmcli con mod ens160 ipv4.dns 223.5.5.5 119.29.29.29 nmcli con mod ens160 ipv4.ignore-auto-dns yes nmcli con up ens160这里第一个命令把DNS设置为两个第二个命令是告诉NetworkManager忽略DHCP下发的DNS第三个命令重新激活连接让配置生效。注意别漏掉第二行否则DHCP一刷新DNS又变回去了。如果你习惯直接改配置文件也可以编辑 /etc/sysconfig/network-scripts/ifcfg-ens160注意接口名要对应在里面加这样几行DNS1223.5.5.5 DNS2119.29.29.29然后重启网络systemctl restart NetworkManager。Ubuntu 22.04 上的做法又不一样。因为默认是 netplan 管理网络DNS配置要写在 /etc/netplan/ 下的yaml文件里。比如network: version: 2 ethernets: ens33: dhcp4: true nameservers: addresses: [223.5.5.5, 119.29.29.29]改完执行sudo netplan apply生效。要注意yaml的缩进不能乱我吃过好几次亏一个空格缩进错了直接导致整个网络配置不生效连SSH都断了。所以建议改netplan前先看一眼cp /etc/netplan/*.yaml /tmp/backup/并且用sudo netplan try来测试它会在一段时间后自动回滚防止你把自己锁在外面。2.3 NetworkManager 和 systemd-resolved 之间的纠缠这两个服务是目前Linux DNS配置最大的“变数”。先理清它们各自管什么。NetworkManager 负责网络连接管理包括IP、网关、DNS的获取和下发。它本身不提供DNS解析服务但可以把获取到的DNS写到 /etc/resolv.conf或者转发给其他服务。systemd-resolved 是一个本地DNS缓存和解析服务通常监听 127.0.0.53:53。NetworkManager 拿到DNS后如果检测到 systemd-resolved 在运行会把DNS配置交给它然后 systemd-resolved 再通过 /run/systemd/resolve/stub-resolv.conf 对外提供统一的解析入口而 /etc/resolv.conf 就符号链接到这个文件。在这种架构下如果直接用 nmcli 设置了DNS实际上十有八九会写入 systemd-resolved 的配置里。如果你想手动指定 systemd-resolved 的DNS可以编辑 /etc/systemd/resolved.conf[Resolve] DNS223.5.5.5 119.29.29.29 FallbackDNS8.8.8.8 DNSSECallow-downgrade重启服务systemctl restart systemd-resolved。但这里有个很反直觉的地方如果你把 /etc/resolv.conf 直接改成一个普通文件删掉符号链接然后写死nameserver那么 systemd-resolved 的缓存就有可能绕过。虽然大部分应用走的是 glibc 的解析顺序但有些依赖 systemd-resolved 接口的高级特性比如DoT就用不上了。所以我的建议是不要轻易把符号链接换掉除非你明确知道自己在做什么。2.4 网卡配置文件里的DNS设置与系统级配置的优先级还有一个容易混淆的点IP地址配置和DNS配置虽然都在网卡上但优先级和生效机制不同。在一个网卡上可以用静态IP同时指定DNS也可以用DHCP获取IP但DNS用静态值。关键区别在于 DHCP 是否会覆盖你手动指定的DNS。比如在 RHEL 系里ifcfg 文件的 PEERDNSyes 表示允许DHCP下发的DNS覆盖配置文件里的DNS1/DNS2。如果不想被覆盖就设 PEERDNSno。同理在 Debian 系的 /etc/network/interfaces 里iface eth0 inet dhcp 这种写法天然会接受DHCP的DNS除非你加上dns-nameservers关键字并配合 resolvconf 使用。在 systemd-networkd 环境下配置写在 /etc/systemd/network/ 下的 .network 文件[Network] DHCPyes DNS223.5.5.5这里有个细节写在[Network]段的DNS是全局性的不管DHCP拿到什么只要你在[DHCP]段设置UseDNSno就不会被DHCP覆盖。生产环境中我一般遵循一个原则能显式写出DNS就显式写不要依赖DHCP下发的DNS尤其是在内网环境里。因为你很难控制DHCP服务器那边会不会给一个不可用的地址而一旦DNS断了所有依赖域名的监控、日志、yum源都会出问题故障面会非常大。3. 配置过程中的常见坑与解决方案3.1 resolv.conf 每次重启就被改写怎么止住这是被问得最多的问题。解决思路是先定位是谁在改它。给你一套排查口诀“先看链接再看服务最后找NetworkManager”。第一步执行ls -l /etc/resolv.conf如果输出里带箭头比如/etc/resolv.conf - /run/systemd/resolve/stub-resolv.conf那就是 systemd-resolved 在管。如果想手动接管可以先删掉这个链接再创建自己的文件rm -f /etc/resolv.conf echo nameserver 223.5.5.5 /etc/resolv.conf但如果系统里还有NetworkManager它可能在某个时间点把这个文件改回去。更稳妥的做法是给NetworkManager做个“持久化配置”用 nmcli 写连接配置文件的 DNS或者直接禁用 NetworkManager 对DNS的改写的选项编辑 /etc/NetworkManager/NetworkManager.conf在 [main] 段加dnsnone然后重启 NetworkManager。dnsnone的意思是NetworkManager完全不管 /etc/resolv.conf让其他工具来管。这样你手动写的 nameserver 就不会被覆盖了。不过要注意如果你同时开着 systemd-resolved这个方案可能还是不生效。我建议要么只用systemd-resolved并用resolvectl管理DNS要么只用手动管理两者不要混着来。3.2 systemd-resolved 带来的 /etc/resolv.conf 符号链接问题Ubuntu 22.04 默认启用了 systemd-resolved很多人在这个系统上手动改 /etc/resolv.conf改完发现不生效很抓狂。原因就是 /etc/resolv.conf 实际是一个符号链接指向 /run/systemd/resolve/stub-resolv.conf。而 /run 目录下的文件是运行时生成的重启服务或重启系统就会被重新创建。如果你确实想绕开 systemd-resolved可以用 systemd-resolved 提供的命令行来正确配置它而不是绕过它。比如resolvectl dns ens33 223.5.5.5 resolvectl flush-caches这条命令会临时改变接口 ens33 的DNS但不会永久保存。永久保存需要改 /etc/systemd/resolved.conf 或者在 netplan 里配置 DNS。还有一点systemd-resolved 默认把 /etc/resolv.conf 指向到的 stub-resolv.conf 只监听 127.0.0.53 这个地址。如果你在容器里或者在chroot环境里使用 glibc 解析原本的 127.0.0.53 可能不可达因为容器里没有 systemd-resolved 的进程监听。我遇到过几次容器内 ping 域名解析不出的问题最后都是因为容器里只看到 127.0.0.53但实际上没有服务在那监听。解决方案是在容器里要单独写 /etc/resolv.conf或者把主机的 DNS 地址直接带进容器。3.3 DHCP 和静态IP下的DNS差异DHCP 和静态IP下DNS配置的行为完全不一样。DHCP 模式下客户端的DNS通常由DHCP服务器的 option 6 字段下发。这个字段指定了DNS服务器的IP地址列表客户端拿到后自动写入 /etc/resolv.conf。如果你在 DHCP 模式下还手动指定了 DNS那么关键看 DHCP 客户端是否允许你覆盖。以 dhclient 为例配置文件是 /etc/dhclient.conf里面可以加supersede domain-name-servers 223.5.5.5;这个命令会强制让 dhclient 使用你指定的DNS覆盖DHCP服务器下发的。在 systemd-networkd 下对应的是 .network 文件里UseDNSno加DNS。静态IP模式下DNS完全由你自己控制比较好理解。但有个坑很多人配置静态IP时只填了IP和网关DNS没填这样解析请求会落到系统默认的空值上然后超时。还有一些人填了不存在的网关地址导致网络虽然显示connected但数据包发不出去DNS自然也不通。所以检查DNS问题时先确认网关能ping通再确认DNS服务器能ping通。3.4 多个DNS服务器优先级与超时逻辑glibc 解析器的行为是按 /etc/resolv.conf 里 nameserver 的顺序逐个尝试如果第一个没有在 timeout 时间内返回就尝试第二个。注意这个“没有返回”定义为超时而不是“返回NXDOMAIN”。如果第一个DNS服务器响应说“域名不存在”解析器会直接返回失败不会去问第二个。所以当你在 /etc/resolv.conf 里配置了内网DNS和外网DNS两个nameserver时如果内网DNS能解析内网域名但对公网域名返回NXDOMAIN那么外网域名就解析不了。这不是bug是设计如此。因此在生产环境里不要轻易把两个功能不互补的DNS放在同一级别。如果你的机器需要同时解析内网域名和公网域名最好的做法是使用一个能够条件转发或者递归查询的DNS服务器比如自建 dnsmasq 或者 unbound把内网和公网域名的解析统一到一个入口然后客户端只配置这一个DNS地址。另外options 参数也可以调节超时和重试次数。比如在 /etc/resolv.conf 里加一行options timeout:2 attempts:1意思是超时从默认5秒改成2秒重试次数从默认2次改成1次。这样如果第一个DNS不可用总共等待时间从10秒降到2秒对服务调用方敏感的场景很有用。但要注意减少重试也会降低在轻微网络抖动下的稳定性需要权衡。4. 排查DNS问题的实用工具和排查思路4.1 先用 dig/nslookup 定位问题范围排查DNS问题第一步永远是手动解析一下域名看是整体不工作还是某个域名解析不了。我习惯用dig而不是ping因为它直接显示解析过程不会受ICMP协议限制。dig 223.5.5.5 www.baidu.com这个命令指定用 223.5.5.5 来解析如果返回了A记录说明该DNS服务器本身没问题。如果不指定 dig会使用 /etc/resolv.conf 里的第一个nameserver。再看一下dig trace命令它会从根服务器开始逐级查询直到拿到答案。这个能在出现解析失败时帮你定位是根服务器、顶级域服务器还是权威服务器出问题。比如你查一个 .com 域名先问到 .com 顶级域服务器然后顶级域服务器返回该域名的权威NS最后再从权威服务器拿A记录。如果你看到某一步返回了 REFUSED 或者无响应就说明故障点在那一段。nslookup 是另一个经典工具适合简单查看。不过它已经有点老输出信息不如dig丰富。我在脚本里更常用的是getent hosts因为它直接走 glibc 的解析流程和实际应用的行为一致。比如getent hosts www.baidu.com如果 getent 能解析但 curl 不行说明问题不在DNS而在应用层的配置比如代理环境变量。4.2 测试不同端口下的DNS连通性DNS协议默认走UDP 53端口但在某些网络环境下UDP 53会被防火墙阻断导致解析超时。这时候可以改用TCP 53测试因为DNS也支持TCP查询。命令行可以用dig tcp dnssec 223.5.5.5 www.baidu.com如果TCP查询成功说明DNS服务器本身没问题只是UDP被拦了。这个现象在云厂商VPC里偶尔会遇到因为网络ACL默认只放行必要端口有人会把UDP 53给drop了。遇到这种情况需要检查安全组和网络ACL规则。另外也可以用nc或者telnet直接测到DNS服务器的TCP 53端口通不通nc -vz -w2 223.5.5.5 53还有一个小技巧在检查DNS服务器是否可达时不一定非要 ping DNS服务器的IP有些公共DNS服务器不响应ping比如8.8.8.8在某些网络环境就是ping不通但能正常解析。所以更靠谱的方式是用 dig 去查一个已知的域名通过返回结果判断可用性。4.3 从系统日志和状态反推故障如果解析失败系统的日志可能是关键证据。在 systemd 环境下可以用journalctl -u systemd-resolved查看 systemd-resolved 的日志。如果配置了 DNSSEC还能看到验证失败的具体原因。NetworkManager 的日志同样有参考价值journalctl -u NetworkManager -f当你执行网络相关操作时日志里会出现 DNS 配置更新的记录比如DHCP: option 6 (dns),DNS: nameserver updated等等。如果系统用的是 resolvconf 作为中间层Debian系老版本常见查看resolvconf -l可以列出当前所有网卡的DNS配置。它本质上是一个把多个来源的DNS信息合并成一份 /etc/resolv.conf 的工具。排查问题时就经常会发现是某个网卡对应的DNS配置覆盖了另一个。还有一种情况是缓存污染。比如你在一台服务器上临时改过 /etc/hosts后来删了但某些进程仍然会解析到旧IP因为系统里还有 nscd 或 systemd-resolved 的缓存。遇到这种问题清除缓存systemd-resolve --flush-caches # 老版本 resolvectl flush-caches # 新版本如果是 nscd 在跑执行systemctl restart nscd或者nscd -i hosts。4.4 巡检脚本一键检测DNS健康我在维护几十台服务器时写过一个简单的巡检脚本可以快速扫出DNS配置异常的主机。核心逻辑是取 /etc/resolv.conf 里的 nameserver 列表然后逐个测试解析公共域名并记录延迟。脚本核心部分类似这样for ip in $(awk /^nameserver/ {print $2} /etc/resolv.conf); do echo --- Testing DNS server: $ip --- dig $ip time3 tries1 www.baidu.com noall answer stats | grep -E Query time|status done如果输出里 status 是 NOERROR 并且 Query time 在可接受范围内基本说明这个DNS可用。如果 status 是 SERVFAIL 或者 REFUSED就说明这个DNS对请求有问题。脚本可以加一个阈值判断比如超过500ms就告警。对很多公司来说内网DNS服务器往往是备用的但内网DNS偶尔也会配置错误导致把公网域名也拦截了。所以在巡检里也建议测试一下内网域名解析比如你公司的 gitlab 域名或监控域名。写个数组把需要检查的域名都列出来定期跑一遍能在故障初期就发现问题。5. 生产环境下的经验补充5.1 配置内网DNS服务器的选型思考如果你所在的环境需要频繁修改DNS策略比如有内部域名解析需求但不想每台客户端都手工指定那么自建一台内网DNS服务器是个好思路。常见选择是 dnsmasq 和 unbound。dnsmasq 轻量、配置简单适合小规模环境。它支持把内网域名记录写在 /etc/hosts 或者专门的配置里然后转发其他查询到上游公共DNS。常见的 /etc/dnsmasq.conf 关键配置就这几行listen-address192.168.1.10 server223.5.5.5 server119.29.29.29 address/internal.example.com/192.168.10.20unbound 则更专业支持递归查询、缓存、DNSSEC验证配置复杂度也更高。我个人的建议是如果你只是需要局域网域名解析用dnsmasq就足够了半天就能搭起来如果你还需要做安全过滤或策略控制可以用 unbound 加 forward-zone 和 local-zone灵活性更高。客户端配置上只需要把 /etc/resolv.conf 的 nameserver 指向这台内网DNS服务器就行。这样后续修改域名解析策略只需要改服务器端客户端不用动运维负担会小很多。5.2 不同发行版的差异化处理速查表为了方便参考我把常见发行版的DNS管理方式整理成一张表不同地方的配置位置和重启命令都不同。发行版/系统主要管理工具配置文件位置推荐配置命令RHEL/CentOS 7/8/9NetworkManager/etc/sysconfig/network-scripts/ifcfg-*nmcli con modRocky Linux / AlmaLinuxNetworkManager同上nmcli con modUbuntu 18.04/20.04/22.04netplan systemd-resolved/etc/netplan/*.yamlnetplan applyDebian 11/12NetworkManager 或 ifupdown/etc/network/interfaces 或 /etc/NetworkManagerifupdown 或 nmcliopenSUSEwicked 或 NetworkManager/etc/sysconfig/network/ifcfg-*yast2 dns 或 nmcliArch Linuxsystemd-networkd 或 NetworkManager/etc/systemd/network/*.networknetworkctl 或 nmcli这张表只列了主线方案实际生产环境里还会遇到非常老的系统比如CentOS 6。旧系统直接用 /etc/resolv.conf 就行因为它是 sysvinit 时代没有NetworkManager接管改了基本就生效。但这类系统多数已经EOL不建议新部署如果遇到只能说能做短期应急处理。5.3 从安全视角看DNS配置DNSSEC与加密DNS最近几年DNS安全越来越受重视。默认的DNS查询是明文走UDP 53中间任何节点都能看到你访问的域名列表。如果你的工作环境对安全要求高建议开启 systemd-resolved 的 DNSSEC 支持或者在客户端和DNS服务器之间启用DoT/DoH。systemd-resolved 的配置比较简单在 /etc/systemd/resolved.conf 里[Resolve] DNS223.5.5.5 DNSSECyes DNSOverTLSopportunisticDNSOverTLSopportunistic表示如果上游DNS服务器支持DoT就用DoT不支持就退回到明文。如果你要求强制加密可以设成DNSOverTLSyes。要注意强制加密可能导致某些不支持DoT的DNS服务器无法解析。另一个实用工具是dnscrypt-proxy它可以作为本地DNS转发代理把所有的DNS查询加密后发给支持协议的公共DNS服务器。配置相对复杂一点但效果稳定。由于它工作在本地客户端只需要把nameserver指向 127.0.0.1就能无感知地获得加密解析能力。需要提醒的是配置这些加密DNS方案时务必在目标环境先做小范围测试因为有的上游DNS服务器虽然支持DoT但证书链可能有问题导致验证失败。不要一股脑全量替换掉原有DNS配置万一遇到不兼容的上游反而会影响整条解析链路。5.4 容器场景下的DNS配置现在很多业务跑在容器里容器内部的DNS配置和宿主机又有区别。Docker 默认会让容器使用宿主机上的DNS设置通过 docker daemon 的--dns参数或者 daemon.json 里的dns: [223.5.5.5]来控制。容器内 /etc/resolv.conf 的生成逻辑是如果容器没指定--dnsDocker 会从宿主机 copy 一份默认解析配置。很多人在宿主机改了 /etc/resolv.conf但容器不重启就不会生效因为容器启动时才会生成自己的 /etc/resolv.conf。所以修改完宿主机的DNS后记得重建容器或者用docker-compose up -d --force-recreate应用新配置。另外在 Kubernetes 环境里DNS配置是一个集群级别的服务一般由 CoreDNS 提供。节点上 /etc/resolv.conf 往往是集群管理员预先配置好的Pod 内置的解析器会走CoreDNS。这时候如果你直接在Pod里手动改 /etc/resolv.conf因为容器文件系统是临时的Pod重建后就会丢失。真正要改的是集群的 CoreDNS 配置或者给 Pod 指定 dnsPolicy。这算是容器和传统Linux之间最大的差异之一。总结之前的最后提醒因为 DNS 配置这个主题越讲越多我再补一个我常挂在嘴边的经验改配置前先备份改配置后一定验证验证的时候要分开验证“能解析”和“解析结果正确”这两件事。很多人只测了能不能拿到IP没测IP是不是对的。你改了DNS之后拿到的IP却还是旧缓存那就等于没改。还有一个小技巧排查任何网络问题先把自己机器的 DNS 配置列出来再测一下到 DNS 服务器的连通性最后确认系统时间和证书情况。有时候你发现解析出来的IP是错误的不是配置问题而是系统时间差太远导致 DNSSEC 验证失败但系统把它当作解析失败返回了。这种隐藏坑查起来特别费劲但只要想到这层解决起来就一句话同步时间。我实际工作中一半以上的DNS问题都是因为没理解“谁在管这个文件”导致的。如果你看完这篇文章至少记住一点不要盲目去改 /etc/resolv.conf先搞清楚你的系统用的是 NetworkManager 还是 systemd-resolved再选择合适的修改入口问题就解决了一大半。剩下那一半就是按部就班地用 dig 和日志去定位了。
返回列表