你的站没被打,但邻居被 DDoS 打满,出口带宽、清洗池、CDN 节点都是共享的。本文讲清「邻居效应」怎么判断、用哪些命令拿证据、自己这边能做哪些隔离。
Q:同一个机房、同一家 CDN,别人被打我为什么会慢?
- 因为你付的钱买的是资源份额,不是独占资源。出口带宽、上联链路、交换机端口、清洗设备、CDN 边缘节点的 CPU 和连接表,全都是共享的。
- 攻击消耗的是「容量」,而容量是共享的。邻居 10Gbps 打进来,机房 20Gbps 上联就有一半被占,你分到的不是承诺值,而是「剩下的」。
- 三种典型表现:出口拥塞(丢包、延迟抖动)、清洗设备排队(攻击流量进清洗池,你的正常请求也过同一台设备)、节点过载(CDN 某 POP 被刷满连接数)。
- 更要命的是,机房侧的黑洞和限速常常按整段 IP 生效,邻居被打,你跟着进黑洞。
- 所以「我没被打为什么慢」不是玄学,是资源争抢。判断的关键在于:证明你自己的链路和源站是干净的。
Q:哪些「共享」最容易被邻居拖累?
- 机房共享出口:最常见。百兆、千兆共享,超卖比常见 1:4 到 1:10,没人打的时候跑得飞快,一有人被打立刻抽干。
- 共享清洗池:一台清洗设备后面挂几百个站,处理能力是固定的,邻居吃满配额你就排队。
- CDN 共享 POP:单个边缘节点承载几千个域名,攻击时按优先级调度,小客户排在后面。
- 共享 IP:虚拟主机、共享型高防都是这一类,同 IP 上任何一个站被投诉或被封,你一起受影响。
- 共享存储与数据库:不属 DDoS,但同样是邻居问题,慢查询一多全站抖。
Q:怎么判断是邻居问题,不是自己被攻击?
- 第一步,看自己的数:源站入向带宽和 QPS 平稳,但用户侧变慢,基本可以排除「你被打」。
- 第二步,同机房放一台自己的探针,定时请求自己的域名。探针也慢,说明问题在上游或机房。
- 第三步,换出口测:用手机 4G、异地节点各测一遍,看慢点出现在哪一跳。
- 第四步,看时间相关性:变慢的时段是否和你自己的流量峰值、发布、备份任务重合。重合就是自己的问题。
- 第五步,直接问服务商「上联当前是否有攻击或拥塞」。有经验的值班会告诉你大致情况,这个信息比你自己猜快得多。
Q:用哪些命令能把证据拿出来?
- 核心思路是分层定位:先分清是网络层丢包还是应用层排队,再定位丢在哪一跳。
- mtr 要按「最后一跳丢包」读。中途某一跳丢包但末端 0%,通常是那台设备对 ICMP 限速,属正常现象。
- curl 的分段计时最实用:DNS、连接、TLS 都正常,只有 TTFB 变长,说明是服务端或边缘排队,不是链路。
# 1) 丢包从哪一跳开始(建议同时跑 4G 和机房两个出口对比)
mtr -rwzc 100 -P 443 www.example.com
# 2) 分段计时:区分网络慢还是应用/边缘慢
curl -o /dev/null -s -w 'dns=%{time_namelookup} conn=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' https://www.example.com/
# 3) 本机视角的丢包与重传(Linux)
nstat -az | egrep 'TcpRetransSegs|TcpExtTCPLostRetransmit|IpInDiscards'
ss -s
# 4) 连续采 60 次握手,看 RTT 抖动
for i in $(seq 1 60); do curl -o /dev/null -s -w '%{time_connect}\n' https://www.example.com/; sleep 1; done | sort -n | tail -5
- 把 mtr 的输出和 curl 的时序按分钟对齐,就能画出一条「慢从几点开始、慢在哪一层」的线。这份东西拿去开工单,比一句「网站很慢」有用得多。
Q:机房说「共享带宽」,到底在共享什么?
- 出口总带宽与超卖比:100M 卖给 10 个客户,理论峰值各 10M,实际闲时都能跑满,一旦有人被打,池子瞬间见底。
- 95 计费与突发额度:突发是「允许你短时超」,不是「保证你随时有」,攻击期突发最先被收回。
- 上联多线与路由收敛:某条链路被打满触发路由变化,流量挤到其他链路,其他链路上的客户跟着抖。
- 清洗触发阈值:很多机房按 IP 段设置流量阈值,超了整段牵引或黑洞,邻居的锅你背。
- 买之前一定要问:出口是独享还是共享、超卖比多少、清洗设备是独享还是共享池。
Q:CDN 上「邻居被打」有什么特征?
- 命中率没掉、回源 QPS 没涨、源站负载正常,唯独首字节时间变长,或者零星出现 5xx,这是边缘侧排队的典型信号。
- 同一个域名,换个地区访问就正常,说明是局部 POP 的问题,不是你源站的问题。
- 应对办法按成本排序:先切备用 CNAME 到其他节点,再切备用厂商,最后才考虑临时降级页面。
- 静态资源独立域名能降低单域名的连接压力,但要权衡多域名带来的证书和 DNS 成本。
- 如果长期反复出现,说明这家厂商的节点密度不够,该换方案了,而不是继续调配置。
Q:自己这边能做什么隔离?
- 关键业务走独立线路:管理后台、支付回调、API 放在另一条出口或另一个 IP 上,主线路被挤时还能操作。
- 静态资源长缓存:把图片、JS、CSS 的缓存拉到 30 天以上,减少动态链路依赖,邻居再吵你也能出页面。
- 本机做优先级:用 tc 给自己的交互流量保底,避免被备份、日志回传这类大流量任务挤死。
- 注意 tc 只能调度出向流量,入向拥塞它管不了,这是它的边界。
# 出口 1Gbps:443 交互流量保底 300M,其余走低优先级(注意 egress 匹配的是源端口)
tc qdisc add dev eth0 root handle 1: htb default 20
tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 1000mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 300mbit ceil 600mbit prio 0
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 100mbit ceil 400mbit prio 2
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip sport 443 0xffff flowid 1:10
# 查看队列与丢包
tc -s class show dev eth0
Q:采购时怎么问才能避开共享陷阱?
- 六问必答:出口独享还是共享、超卖比多少、清洗设备是否独享、单节点承载多少域名、攻击时我的流量优先级、超量后是限速还是黑洞。
- 把承诺写进合同:攻击期间丢包率与P99 首字节的具体数值,而不是只写「可用性 99.9%」。
- 试用期挑攻击高发时段测,工作日晚上八点到十一点最真实,凌晨测出来的数据没意义。
- 问一句「同段 IP 最近有没有被攻击」,多数销售会说漏嘴。
Q:真被拖累,怎么取证和索赔?
- 三段证据缺一不可:自己侧(nstat、mtr、curl 时序)、第三方侧(多地监控的丢包与响应时间)、服务商侧(工单记录与故障公告)。
- 先看 SLA 条款:绝大多数只赔可用性,丢包和延迟往往不在赔付范围内,别指望靠这个要钱。
- 谈判话术给三段:受影响时段、量化指标(丢包 3%、P99 从 200ms 到 1.8s)、业务损失估算。要求降配退费或延长服务期,比要求现金赔付更容易谈成。
- 如果同一问题一个月出现三次,别再修,直接换供应商,迁移成本远低于反复沟通成本。
Q:还有什么补充建议
- 建一条自己的基线:正常时段的 TTFB、丢包率、带宽曲线。没有基线,「变慢」这件事永远说不清。
- 主备两家:主 CDN 加备 CDN,DNS 按权重切换;但别在同一家既做 CDN 又做高防又做 DNS,一次故障全站挂。
- 预算有限时优先买「独立 IP + 独立出口」,比买大带宽更实在,邻居打不到你的链路上。
- 最后提醒:邻居效应不是要你换掉所有共享资源,而是让你知道哪一层共享、坏了怎么绕。把绕行方案写成文档,出事时能省几个小时。