尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

浏览器请求到不了后台?从DNS到WAF逐层排查实战

浏览器请求到不了后台?从DNS到WAF逐层排查实战 先说个结论这类问题的麻烦之处从来不是后台服务本身有多复杂而是从你敲下回车到请求落到服务端中间隔了太多层看不见的关卡。我在一线处理过不少类似Case前端同事说接口我调了后台怎么没收到网络同事说出口流量我看了没有异常最后花了一下午逐层追查发现只是浏览器侧的一个DNS缓存或者代理设置问题。所以今天这篇我想顺着浏览器流量完整走一遍链路浏览器发出请求之前做了什么、公网和中间设备会怎么处理、后台服务怎么才算真正接到了流量以及遇到问题时怎么逐段排查定位。整篇走的是实际操作路线适合后端开发、运维和经常跟请求到不了后台这类问题打交道的人。1. 请求出浏览器别急着怀疑后台先确认它真的发出去了很多人排查浏览器打不开/请求失败时第一反应是去看后台日志结果日志空空如也就开始怀疑网络。这里我想强调一个原则问题排查的起点必须在浏览器里而不是机房。浏览器是一个相当复杂的软件它不是简单地把请求发出去就完事了前面还有一堆动作要做任何一步卡住请求根本到不了网卡。1.1 F12和net-internals浏览器自带的飞行记录仪浏览器开发者工具里的Network面板就是第一手的飞行记录。打开方式不说了关键是怎么看。一个请求发出后面板上会显示Queueing、Stalled、DNS Lookup、Initial Connection、SSL、Request Sent、Waiting (TTFB)、Content Download这几个阶段。判断问题出在哪一层就看卡在哪个阶段卡在Queueing或Stalled请求还没出浏览器通常是因为同域名并发连接数已满或者浏览器在排队处理其他事务。卡在DNS Lookup域名解析环节出问题解析超时或失败。卡在Initial Connection或SSLTCP握手或TLS握手不顺利通常是网络路径不通、被防火墙拦截、或者MTU问题。Request Sent之后一直Waiting请求确实发出去了问题是后台没有及时响应这才轮到服务端排查。还有一个容易忽略的地方是chrome://net-internals/#dns和#eventsChrome/Edge都保留了这个内部页面。它可以告诉你某个域名当前解析到了哪个IP、连接是否成功、失败的具体原因是什么。注意这里要特别提醒一下开发阶段很多同事用的是本地hosts文件做域名映射但浏览器不一定命中hosts——如果系统开了安全DNSDoH浏览器可能绕过hosts直接走DoH解析到公网IP这种明明配了hosts却不生效的坑我见过不止一次。1.2 DNS解析与缓存第一道看不见的关卡浏览器拿到URL后第一件事不是发请求而是解析域名。这个过程默认走浏览器缓存 - 系统DNS缓存 - hosts文件 - 配置的DNS服务器 - 递归查询这条链。任何一环出问题都会表现为浏览器打不开后台却觉得一切正常。这里有个实际案例用户反馈某个内网系统在Chrome里经常打开慢第一次访问要十几秒刷新后正常。抓包后发现每次首次访问时浏览器都在尝试解析一个已经被域名服务商删掉的旧域名记录超时后才降级到新的解析结果。原因是系统DNS缓存里残留了旧的TTL很长的记录TTL没到之前浏览器根本不知道记录已经失效。处理方式也不复杂CLI下用ipconfig /flushdnsWindows或sudo systemd-resolve --flush-cachesLinux浏览器侧可以临时用无痕模式绕过缓存做对比测试。值得多说一句的是DNS层面的污染或劫持问题。如果你在办公网里通过内网DNS解析外网域名解析结果可能先经过出口设备的过滤规则而在家庭宽带环境下运营商DNS有时会对特定域名做干扰或跳转。验证方法也很简单用nslookup分别查配置的DNS和公共DNS对比解析出的IP是否一致如果不一致问题大概率在DNS这一层。1.3 连接复用、代理设置与浏览器扩展的隐形干预真正建立连接之前浏览器还会干两件事查代理设置、查连接池。代理这块是最容易被忽略的坑。系统代理、PAC脚本、浏览器插件代理比如某些SwitchyOmega类工具都会改写请求的出口。如果代理服务器挂了或策略配置错浏览器可能直接报代理连接失败或者把请求发到了一个你完全没预期的网关。热搜词里wifi打不开网站流量可以打开、某个网站在Chrome打不开Edge能打开这类问题相当一部分是代理设置差异造成的。排查方法浏览器设置里看代理是否开启或者直接临时关闭所有代理插件再做对比。命令行下也可以用curl --noproxy *绕开代理直连看后台是否正常。连接池则是性能层面的隐性因素。HTTP/1.1下浏览器对同一个域名默认最多维护6个TCP连接如果一个页面里有大量并发请求后面的请求会在队列里等前面的连接释放。HTTP/2支持多路复用没有这个限制但如果后台服务、CDN都没开启HTTP/2页面并发高时Connect就慢。很多接口偶发超时但单ping一下又通的问题其实是连接池耗尽后的排队导致而不是网络抖动。浏览器扩展更不用说了。广告拦截、脚本管理、安全防护类扩展都可能悄无声息地拦截掉某些请求尤其是带特定关键词的URL。比如某些扩展会把含有api、analytics字样的请求直接block掉。排查时用无痕模式默认禁用扩展跑一遍同样的操作如果能通基本就是扩展的问题。1.4 不同浏览器的差异为什么Edge正常、Chrome却不正常热搜词里有个跨浏览器支持的设计与实现这里想说的是浏览器之间的差异很多时候不是内核差异而是各自默认策略的差异。Chrome和Edge现在底层都是Chromium协议行为基本一致但三处策略常常不同——安全DNS是否开启、是否自动切换到系统代理、以及TLS1.3的启用情况。一个真实案例同事反馈Chrome访问内部站点报此网站无法提供安全连接Edge却能正常打开。查了很久最后发现Chrome开启了安全DNS把内部域名交给了公共DNS解析解析到外网IP后证书不匹配。而Edge使用了系统配置的内网DNS解析到内网IP证书正常。处理方式是给Chrome的DoH加白名单或在内部DNS层面做策略。类似的老版本IE默认不支持TLS1.2以上如果你的后台只开了TLS1.3老浏览器自然连不上——这种属于上下游协议兼容性协商不在网络通不通的范畴。2. 跨过公网和中间设备从运营商到WAF、CDN、负载均衡各自动了什么手脚数据包离开你的网卡之后才是真正容易失控的地方。很多后台没收到请求的故障其实发生在中间的某个节点上。这一层要讲的不是原理教科书而是几个最常见的动手脚节点以及对应的坑。2.1 运营商DNS与MTUWIFI打不开但流量能打开的背后热搜里wifi打不开网站流量可以是个很典型的现象。手机连着家里WiFi时网页打不开切成移动网络却秒开。这里通常不是后台问题而是链路MTU匹配问题——路由器默认MTU是1500但某些宽带链路实际最大可用MTU只有1492PPPoE场景或者更小。如果你后台服务响应太大超过链路允许的分片大小而通信链路不支持分片数据包就会被悄悄丢弃表现就是小请求正常、大响应卡死或图片加载不出来。排查方法在电脑上ping后台域名用ping -f -l 1472Windows或ping -M do -s 1472Linux测最大可用包大小逐步上调看什么时候不通。如果1472能通而更大的包不通基本可以确认MTU问题。解决方式是把路由器WAN口的MTU改成1492或更小或者收紧后台/中间代理的MTU。另一条线是IPv4/IPv6双栈差异。有些运营商网络IPv6路径不稳定DNS同时返回了A和AAAA记录浏览器优先尝试IPv6连接失败后降级到IPv4这个切换过程会带来明显延迟甚至因为超时机制过长导致页面卡住不动。排查方法是在浏览器里分别测试http://域名和http://IPv4地址加Host头再配合ping -6看IPv6通不通。如果确认IPv6拖后腿可以在系统层临时禁用IPv6做对比。2.2 WAF与风控拦截检测到异常流量提示是怎么来的热搜词里那句话我们的系统检测到您的计算机网络中存在异常流量请稍后重新发送请求——这个提示在不少网站上出现过它要么来自网站的WAF要么来自背后的风控系统。从技术角度讲这类拦截通常基于三个维度的特征第一是请求特征比如User-Agent过旧或为空、缺少某些浏览器必带的请求头、Accept-Language不符合常理。正常浏览器发出的请求头组合是一套相对固定的指纹用curl模拟时如果只带最简单的头WAF很容易判定为机器人。第二是IP信誉出口IP是机房段还是住宅段、历史上有没有攻击记录。如果你所在办公室的出口IP被标过风险整个办公网都可能被拦。第三是行为频率单位时间内的请求数、同一页面上的点击节奏。排查手段把你从浏览器实际复制下来的完整请求头F12里可以右键Copy as cURL原样在别的地方重放一遍看是否被拦。如果被拦就把请求头逐步精简看到底是哪个字段触发了规则。很多情况下加一个正常的User-Agent和Referer就能解决如果确认是IP维度的问题需要对WAF侧加白名单这属于后台侧的策略调整。2.3 CDN回源与网关转发最常见的超时和丢请求节点如果你的服务前面挂了CDN或者云负载均衡那请求路径会多出浏览器 - CDN节点 - 回源 - 后台这一段。这里头最常见的问题是回源配置错误。CDN回源时有三个配置点经常出问题回源HOST、回源协议、回源超时。回源HOST错了后台收到的Host头不是预期域名会导致虚拟主机匹配错误甚至被后台按未配置域名直接拒绝回源协议不一致比如CDN回源用HTTPS但后台只监听了HTTP连接一定失败回源超时设置太短后台处理超过阈值CDN就直接返回502或504。网关/负载均衡层也一样。拿Nginx做反向代理来讲很多502/504其实是以下几个默认参数造成的proxy_connect_timeout默认60秒连接后端超时、proxy_read_timeout默认60秒读取后端响应超时、proxy_send_timeout。如果后台某个接口要做文件导出或AI推理这类长耗时操作响应时间超过代理层的读超时客户端看到的报错和后台日志记录的请求已完成就对不上——每次出问题时大家各说各话就是因为时间线对不齐。3. 服务端的接待能力请求明明到了为什么还是进不了应用确认请求已经到达服务器之后依然不等于能进入你的应用代码。服务器这一侧还有好几层接待人员任何一层不打收条请求就会在门口消失。3.1 监听、防火墙与安全组先确认门口有没有开最基础也最常犯的问题有三个服务监听在127.0.0.1、防火墙放行规则没加、云安全组没放端口。服务只监听127.0.0.1意味着只有本机能访问外部流量到了网卡也会被内核拒绝。检查方法很直接netstat -tlnp看监听地址如果是127.0.0.1:8080那就是它了改成0.0.0.0:8080。防火墙层面Linux下要确认iptables/firewalld有没有放行对应端口云服务器上更隐蔽的是安全组规则——安全组没放行时本机curl localhost通外网访问超时两者不矛盾所以排查时必须在外网视角做验证而不是只在服务器本机测。这里我有个习惯无论什么时候先在服务器上用curl 127.0.0.1验证服务活着再在办公网直接用公网IP加端口验证两步之中的差别就能定位出是不是防火墙/安全组的问题。3.2 TCP队列与TIME_WAIT连接层的隐性瓶颈服务端接受连接的过程有两级队列半连接队列和全连接队列。半连接队列存放已完成SYN握手但还没完成三次握手的连接对应net.core.somaxconn和单个socket的backlog参数全连接队列存放已完成三次握手但等待应用accept()的连接。如果应用处理慢全连接队列会积压新连接在内核层面就开始丢包或延迟浏览器表现就是一直在转圈但迟迟不返回用ss -lnt能看到Send-Q和Recv-Q的值异常偏大。之前帮朋友排查过一个偶发性连接被重置问题后台看日志一切正常但压力测试时并发上千就挂最后发现是backlog太小队列溢出后新连接直接被RST。把somaxconn调大并同步调整应用层listen的backlog参数问题解决。TIME_WAIT则是另一类隐藏问题短连接高频访问时主动关闭连接的一方会产生大量TIME_WAIT状态连接如果tcp_max_tw_buckets上限很小超过后新连接可能无法建立。判断方法是netstat -s | grep timewait或者直接看ss -ant | grep TIME_WAIT | wc -l。解决思路是尽量开启keep-alive复用连接而不是无脑调tcp_tw_reuse——后者在内核版本变更后行为差异很大容易引入新问题。3.3 应用层线程池与超时配置扛得住连接扛不住请求TCP握手成功、连接也accept了请求到了应用层但应用层还在上一轮请求里卡住那么新请求也只能排队。最典型的两个坑线程池被打满、下游依赖超时时间设置太长。以Java系为例Tomcat默认线程池200如果某个接口被慢SQL或下游HTTP调用拖住线程耗尽后新请求全部排队浏览器侧表现为TTFB时间不断上升直到超时。查的时候别只看QPS要盯着Active Threads和队列积压数。另一个是超时配置连接池里的下游调用如果connectTimeout和readTimeout设置不合理上游某个依赖方卡住后请求会像多米诺骨牌一样层层堆积。有个经验值是下游读超时不要超过当前接口自身超时的三分之一而且要配上快速失败和降级逻辑。对于Nginx作为业务入口的场景还有一层要看的是worker_processes和worker_connections。每个worker能同时处理的连接数是有限的ulimit -n限制不放开的话文件描述符耗尽后新连接会被拒绝错误日志里会出现too many open files。这类问题在高峰期偶发、平时正常的服务里很常见。4. 断层排查从现象到根因的一条可靠链路前面把各个节点都过了一遍现在说路径。遇到浏览器请求到不了后台别一层一层瞎猜按照下面这条链路逐段做对照实验绝大多数问题半小时内能定位。4.1 分段抓包与时间线还原谁丢了包一目了然不管现象多乱抓包永远是最可靠的。分段的意思是在浏览器所在机器抓一次看请求有没有真正发出在服务器上抓一次看数据包到底有没有到达。两边同时用tcpdump抓并把抓到的内容按时间戳对齐就能直接判断丢在哪一段。浏览器侧用Wireshark或tshark过滤条件直接写host 你的后台域名/服务器IP。关注三个关键事件DNS解析请求、TCP的SYN包、TLS的ClientHello。服务器侧同样抓这三个事件。如果浏览器侧有SYN发出但服务器侧没有任何包到达说明丢在中间链路重点查防火墙/安全组/运营商路径如果服务器侧收到了SYN但没完成握手重点查TCP队列和syn_backlog如果完整握手都完成了却没有HTTP请求内容重点查代理转发逻辑。对齐时间线时有一个容易犯的错误服务器和本机时钟不同步明明同时发生的包在两边看相差几十秒。所以抓包前先看两边时间偏差大的先调整时钟再分析不然会产生定位误导。4.2 浏览器与curl的结果差异反推问题在浏览器还是链路这种方法特别好用我基本每次排障都会做一遍。构造相同的访问请求分别从浏览器和命令行发起对比结果浏览器失败、curl成功问题在浏览器侧。优先怀疑DNS缓存、代理、扩展、HSTS、安全DNS这几个点按1.3和1.4讲的思路排查。curl失败、浏览器成功问题大概率在curl模拟的请求不完整比如缺少某些请求头被WAF拦了或者HTTP版本不一致、TLS指纹不同。这时用浏览器的Copy as cURL功能原样复制再在命令行执行就能复现出浏览器的真实请求环境。两边都失败问题在中段或后台接下来按4.1的思路抓包同时看后台应用日志是否收到。curl模拟时记得加-k跳过证书校验用于排查证书环节、-v打印完整握手过程、-w输出各阶段耗时。一条典型的命令长这样curl -kv -w DNS:%{time_namelookup}s TCP:%{time_connect}s TLS:%{time_appconnect}s TTFB:%{time_starttransfer}s Total:%{time_total}s\n https://api.example.com/test输出的几个时间点分别对应DNS解析、TCP握手、TLS握手、首字节响应一眼就能看出卡在哪一环。4.3 三个典型故障的完整排查记录案例一页面偶发504后台日志无记录。现象是浏览器F12里请求状态504但后台Nginx访问日志压根没有这条请求。排查过程先在后台服务器抓包发现请求确实到了Nginx但响应前连接被网关断开再查网关配置发现proxy_read_timeout设了10秒而后台那接口正常要跑15秒以上超过阈值后网关直接断开。这是典型的超时时间配置与业务耗时不匹配。案例二Chrome报网络异常流量。用户访问一个电商页面输入一次就弹出异常流量提示。重放curl加了完整浏览器头也会被弹。最后发现是办公室出口公网IP被风控标记原因是同一IP下有人跑过爬虫脚本。处理方式是风控侧对该IP加白名单同时要求脚本侧改走专用出口。这个案例说明问题出在IP信誉这种看不见的维度不是代码能解决的。案例三接口在部分网络环境通、部分不通。排查后发现IPv6路径不通浏览器尝试走AAAA记录时反复超时降级到IPv4后能通但降级过程长达数十秒。方案是后台DNS只返回A记录暂不提供AAAA让所有请求统一走IPv4联通性恢复。这类问题在移动办公场景里越来越常见值得多留意。5. 让流量稳稳着陆的配置基线与实践建议排查经验积累到最后我觉得最有价值的不是修好一个个问题而是提前把容易出问题的地方都钉死。这一部分列一些实际在用的配置基线可以直接当模板抄。5.1 浏览器侧配合开发自测时如何排除干扰开发联调阶段为了不让浏览器自身的策略干扰问题判断我建议先做三件事用无痕窗口天然禁用扩展、关闭代理或至少在浏览器设置里确认代理配置、必要时临时把安全DNS关掉。这三条能排除掉大部分浏览器拦住了请求的因素。另外如果你在本地改hosts做联调记得同时关掉系统的网络代理很多抓包工具会自动设置代理导致流量走了代理而不是直连。联调完成后恢复hosts时也顺手清一下DNS缓存避免残留记录影响后续测试。可以养成一个习惯遇到页面打不开但后台看起来正常第一分钟就把chrome://net-internals/#sockets和#dns打开看看这个习惯比什么工具都管用。5.2 中间层与后台侧配置基线针对中间层常用的稳妥配置是这样一组基线Nginx反代的超时设置建议放宽到业务最慢接口的1.5倍proxy_read_timeout、connect_timeout都要单独评估不要统一塞一个值。后端服务务必开启HTTP keep-aliveHTTP/1.1或HTTP/2都能显著降低握手开销也能减少TIME_WAIT堆积。TCP层排查维护somaxconn建议设1024以上根据并发量评估tcp_max_syn_backlog、netdev_max_backlog保持默认偏大即可不建议盲目调整所有内核参数。防火墙策略要有明确清单哪些IP段可以访问哪些端口避免为了排查问题就全放开的临时操作这种临时动作最容易泄漏到生产环境。后台服务侧线程池和超时配置建议做成独立参数方便压测时快速调整。压测前先把ulimit -n放开ulimit -n 102400这类再确认应用层最大连接数、线程池上限、数据库连接池三个数值能相互匹配不然任何一个短板都会在流量上来时暴露。5.3 主动拨测与留痕别等问题发生了才开始查最后的建议是建立主动拨测机制。用一个最简单的HTTP客户端每隔1到5分钟访问一次关键接口记录DNS耗时、TCP耗时、TLS耗时、首字节时间并发出告警阈值。这样绝大多数链路问题会在真实用户感知之前暴露。拨测的目标地址建议同时覆盖本机回环地址、后台内网地址、经负载均衡/网关的域名地址三段分开监控哪一段出问题直接指向对应层级。抓包数据建议保留一部分原始包尤其是问题频繁的时间窗口。真实排障时很多人过了一天才来说昨天有个问题如果当时没留包很多过程细节根本没法回溯。我自己的习惯是重要服务的核心入口一直开着tcpdump的环形缓冲比如保留最近10分钟的数据包只抓80/443端口平时不占多少磁盘出问题时马上暂停包就在那里等着。我不太建议把所有参数都调到极限。内核参数、连接池、超时设置的目的是让服务在预期容量内稳定运行而不是为了扛意外流量去拼命调大。根据我几次线上排障的经验意外流量来临时快速定位和恢复靠的往往是清晰的链路认知和完整的监控数据而不是某个万能参数。先理解浏览器到后台这条路上每一站发生了什么再谈调优你会省掉大量排查半天、其实连问题在哪一层都没搞清的时间。
返回列表