一个斜杠引发的CDN资源回源请求量飙升
背景
一个安静的晚上,突然接到小伙伴电话线上CDN回源异常,具体表现为请求量飙升,且伴有少量请求404,其中回源请求量飙升已经持续两天但一直未被发现,直到最近404请求触发了告警后分析log才同时发现回源量飙升这一问题。
触发问题的原因很快被发现并修复上线,这里分享一下跟进过程中进一步学习到的CDN回源策略、301触发机制原理等相关概念与知识。
多余斜杠(/)引发的流量飙升
大量301
通过查看源站nginx log,发现回源请求量比上周同一天飙升近1000倍,甚至开始怀疑是不是CDN厂商那边出问题了,进一步分析log后发现源站对于CDN的回源请求基本上都是301(Move Permanently)响应,此类响应占了95%以上,301表示永久重定向,这说明绝大部分回源请求都会被源站重定向到另一个地址。
咨询CDN厂商后确认,CDN节点对于源站的301请求默认是不跟随的,即CDN节点不会代为跳转到最终地址并缓存在本地后返回,而是直接返回给客户端301,最终由客户端自行进行301跳转。
那突然飙升的301请求是怎么来的?查看nginx 301请求的path后很快发现所有的CDN图片资源地址的path开头多了一个/,比如http://cdn.demo.com/image/test.jpg 会变成 http://cdn.demo.com//image/test.jpg ,此类请求源站会直接返回301 Location: http://cdn.demo.com/image/test.jpg ,即要求用户301跳转至去除多余/的版本。
这就产生了一个疑问,印象中源站的文件server是没有这种类似301的处理机制,那这个合并/的操作难道是发生在nginx?然而印象中nginx也没有进行过类似配置。
nginx的merge_slashes
再次check文件server代码确认没有合并/的301处理逻辑,并经过实测后确认其实是nginx做了这一步301的处理,nginx配置中有一个merge_slashes配置,官方文档说明如下:
Syntax: merge_slashes on | off;
Default: merge_slashes on;
Context: http, server
Enables or disables compression of two or more adjacent slashes in a URI into a single slash.
Note that compression is essential for the correct matching of prefix string and regular expression locations. Without it, the “//scripts/one.php” request would not match
location /scripts/ {
...
}
and might be processed as a static file. So it gets converted to “/scripts/one.php”.
Turning the compression off can become necessary if a URI contains base64-encoded names, since base64 uses the “/” character internally. However, for security considerations, it is better to avoid turning the compression off.
如上所示merge_slashes默认是开启的,其作用是将URI中多于2个的连续/合并为一个单一的/,也就是说无论是cdn.demo.com//a.jpg 还是cdn.demo.com///a.jpg , 都会被合并为cdn.demo.com/a.jpg 。
多余的/到底哪来的
没错,这是个低级错误--几天前刚修改了图片文件CDN URL组装的模块代码,赶紧回去diff一看发现图片资源model生成代码中有一行本地测试代码给手抖提交了(尴尬==!),其最终效果就是导致所有CDN图片资源的URL path开头都会多出一个/,这多出的一个/只会导致图片加载变慢一些而非加载失败,所以大家使用app的时候也没有发现什么问题。
立刻把导致多余/的测试代码注释掉上线,并清理了一波线上相关缓存后,再回过头来观察源站的nginx log请求量肉眼可见的急速下降,后续少量404请求也逐渐消失了。
少量资源404怎么来的
虽然404请求也消失了,但是404出现的原因却依然没有定位到,整体来说404请求数量只有301请求的1%左右,而通过分析log发现404请求开始出现与消失的时机基本上与大量301请求的出现与消失是保持一致的,看上去两者直接是有相关性的。
仔细check 404请求的log,发现其path也很有规律,如:
GET /demo/image/icon.png,/demo/image/icon.png
GET /demo/image/profile.png,/demo/image/profile.png
GET /demo/image/head.png,/demo/image/head.jpg
拿这些path拼装完整URL如http://cdn.demo.com/demo/image/icon.png 其实是能成功获取到资源的,也就是说这些资源肯定是存在的,只是莫名原因客户端请求时其path部分重复拼接了一次,对应请求http://cdn.demo.com/demo/image/icon.png,/demo/image/icon.png 自然就是404了。
从整个CDN文件请求的流程上来说,存在四种可能:
- 首先怀疑的是服务端在拼接CDN URL时出错导致path重复拼接了,但是代码上确实没有找到值得怀疑的地方。
- CDN节点在转发源站的301请求到客户端时响应的Location给拼接错了,考虑到CDN作为一个广泛使用的产品提供给这么多用户使用,CDN节点出错的可能性很低。
- nginx在merge /后给出的301响应中的 Location 给错了,考虑到nginx这么千锤百炼的产品这种可能性极低。
- 不由得回忆起千奇百怪的android机型可能存在千奇百怪的各种情况(踩过的各种坑...),是不是某些小众机型在301跳转时其跳转机制存在问题?可惜源站并直接不能收到客户端的原始请求,因此无法分析此类404请求具体的客户端相关参数,暂时无法进一步分析。
因此目前只能从出现时机上推断404与大量请求的301出现有关联性,但是具体是哪一步有问题还没有办法定位--欢迎大家不吝赐教给出新的可能思路--在301问题修复后404请求已消失,暂且只可遗留至未来有缘再见了。
请求飙升而流量未飙升之谜
问题修复后突然疑惑为什么请求量飙升*1000+的数天,源站带宽没有被打爆呢?源站购买的带宽可是扛不住这*1000的流量呀!
仔细一思考后了然:因为这新增的的请求都是nginx直接返回的301而非实际目标文件,后续客户端301跳转到正确的URL请求后就进入正常的CDN回源->缓存->返回流程了,并不会给源站带来额外消耗。一个完整的301响应也就几百字节,所以实际对于带宽的消耗很小,1000个301响应所占的带宽也就相当于一张几百KB的图片占用带宽而已,所以万幸这一步带宽并没有出现问题。
总结
回顾本次事故,手抖真是万恶之源,本来是新增部分代码,结果不小心把之前的测试代码带上导致CDN 301请求飙升,具体对用户的影响:
- 所有图片类CDN请求均会多一次301跳转,根据用户所属地理位置与源站的距离加载耗时新增几到几百ms不等。
- 大约有1%左右的图片请求会因为重复拼接的path而被响应404。
行走码湖这么多年,终究还是踩下了这个测试代码提到线上导致事故的程序员经典大坑之一,引以为戒,引以为戒!
转载请注明出处,原文地址:https://www.cnblogs.com/AcAc-t/p/cdn_nginx_301_by_merge_slashes.html
参考
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/301
https://cloud.tencent.com/document/product/228/7183
https://www.cnblogs.com/AcAc-t/p/cdn_nginx_301_by_merge_slashes.html
http://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes
https://juejin.cn/post/6844903850625761288
一个斜杠引发的CDN资源回源请求量飙升的更多相关文章
- 不走标准路的微软:少一个斜杠的URI Path
今天又被微软不按标准的做法折腾了一下,写篇博文抱怨一下. 我们先来看一下IETF(Internet Engineering Task Force)对URI结构的标准定义(链接): 注意上面的path部 ...
- (转载)PHPCMS V9专题路径多了一个斜杠的解决办法
PHPCMSV9的专题,在设置生成静态并且网站的静态设置成生成在根目录的时候,专题路径的URL中会多出一个斜杠,如:http://www.2cto.com//special/ddos/ ,我只能说这是 ...
- CDN设置回源host的意义
CDN设置回源host的意义 如果CDN后端用户的的源站web服务上没有绑定加速域名,只绑定了其他域名,未限制域名访问(比如通过服务器IP可以访问到默认网站),可以在CDN控制台填写回源host,这样 ...
- Eclipse进行Debug时断点上有一个斜杠,并且debug没有停在断点处
断点上有斜杠,这是由于设置了Skip All Breakpoints的缘故,调试会忽略所有断点,执行完,只需取消Skip All Breakpoints即可,操作:Run-->Skip All ...
- 别让CDN的回源把你的服务器拖垮,采用正确的回源策略
我们有一台服务器提供的服务主要是以动态页面为主,静态页面都是固定的内容平时更新的很少,最近这台服务器的应用升级到了新版本访问量增大了不少,随之的问题就来了,最近每天一到9点负载就超过警戒值,然后负载持 ...
- 在eclipse程序中设置的断点上有一个斜杠,正常启动debug不能够跳转到debug页面,怎么解决
在run菜单里面,把skip all breakpoints 选项勾去即可,这个选项可能是你无意间选上的.
- js 获取字符串中最后一个斜杠后面的内容
var str = "/asdasf/asfaewf/agaegr/trer/rhh"; var index = str .lastIndexOf("\/"); ...
- 10. js截取最后一个斜杠后面的字符串
var startIndex = filePath.lastIndexOf("\\"); endIndex = filePath.lastIndexOf("." ...
- js截取最后一个斜杠之后的内容
var str = "/asdasf/asfaewf/agaegr/trer/rhh"; var index = str .lastIndexOf("\/"); ...
- 【解决了一个小问题】golang go.mod中多了一个斜杠导致replace无效
replace github.com/sxxx/common_lib/src/ => ../../common_lib/src 修改成 replace github.com/sxxx/commo ...
随机推荐
- web端测试的测试点和注意事项【转载】
文章来源:作者:simplesally 出处:https://www.cnblogs.com/simple1025/ [转载] 工作中接触了不同类型的web端系统,内容不同,需求不同,测试关注点也 ...
- 浙大版《C语言程序设计(第3版)》题目集 习题3-1 比较大小(10 分)
本题要求将输入的任意3个整数从小到大输出. 输入格式: 输入在一行中给出3个整数,其间以空格分隔. 输出格式: 在一行中将3个整数从小到大输出,其间以"->"相连. 输入样例 ...
- 20201003--统计数字字符个数(奥赛一本通 P98 1--字符类型和字符数组)
输入一行字符,统计出其中数字字符的个数 输入:一行字符串,总长度不超过255 输出:一行,输出字符串里面数字字符的个数. 样例输入:Peking University is set up at 189 ...
- 美国:KDB 986446 D01已生效
1.美国FCC认证新要求 继2022年11月25日FCC发布了FCC 22-84法规禁止授权被认为对美国国家安全构成威胁的通信和视频监控设备后,2023年1月24日FCC又发布了KDB 986446 ...
- 1,权限问题:无法创建目录"**": 权限不够":
1,权限问题:无法创建目录"**": 权限不够": 解决:在命令前加上 sudo 命令后,输入密码即可 原创建目录命令:mkdir [选项] DirName 解决权限问题 ...
- 一种典型的不知循环次数的c语言循环问题
问题如图 代码如下 1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include<stdio.h> 3 int main() 4 { 5 puts(&quo ...
- JNI接口的实现
JNI接口的实现 什么是JNI 说明:JNI 是 Java Native Interface 的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++,但是它并不妨碍你使用 ...
- ajax json php post 方法
1.前端 <script type="text/javascript"> function LoadData(arg){ arg.dept=$("#DeptS ...
- openstack安装部署私有云详细图文
本文主要分享的是云计算.openstack的使用.私有云平台建设.云服务器云硬盘的构建和使用.从基本概念入手到私有云建设,信息量非常大.对于openstack的安装部署都是从官方文档中一步步的介绍,内 ...
- css scoped和moudle
scoped css 官方文档 缺点 一.如果用户在别处定义了相同的类名,也许还是会影响到组件的样式. 二.根据css样式优先级的特性,scoped这种处理会造成每个样式的权重加重了: 即理论上我们要 ...