一、问题报告
昨天运维报告江苏移动25上的缓存服务器无法缓存带有防盗链的音频文件,访问日志access.log中大量报如下错误
1430129072.554 677 206 [18:04:32] 100.113.23.233 "GET http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=19FB11C8395A01D9CE783CFCFEDF2140EA9436C20B5BD93227AD1BC51455824F&guid=000000002e4c4b0cffffffffeff7fde3&fromtag=57 HTTP/1.1" 103374 "119.188.138.106" TCP_MISS:DIRECT http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=19FB11C8395A01D9CE783CFCFEDF2140EA9436C20B5BD93227AD1BC51455824F&guid=000000002e4c4b0cffffffffeff7fde3&fromtag=57 "QQMusic 5000025(android 4.4.2)" audio/mp4
1430129072.653 495 206 [18:04:32] 10.32.51.88 "GET http://cc.stream.qqmusic.qq.com/M500004KpNVr0EdY0v.mp3?vkey=F24195287147666C57B468215518D8A79F31C52A85928D0C45C47762FA1FBDB5&guid=CDF0EFB91301874173DACC6DB5DB719F HTTP/1.1" 31417 "119.188.138.106" TCP_MISS:DIRECT cc.stream.qqmusic.qq.com "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.00; MP222)" audio/mpeg
1430129072.721 2237 206 [18:04:32] 112.3.203.4 "GET http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=886E06F11EBF8ECB373A6A46CDEA633E3438368FC792736E3A78C8D9E05B6F0A&guid=0000000002f96916da5843ece9fb27fe&fromtag=57 HTTP/1.1" 103374 "119.188.138.106" TCP_MISS:DIRECT http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=886E06F11EBF8ECB373A6A46CDEA633E3438368FC792736E3A78C8D9E05B6F0A&guid=0000000002f96916da5843ece9fb27fe&fromtag=57 "QQMusic 5010100(android 4.2.2)" audio/mp4
1430129072.964 124 206 [18:04:32] 10.32.51.88 "GET http://cc.stream.qqmusic.qq.com/M500004KpNVr0EdY0v.mp3?vkey=F24195287147666C57B468215518D8A79F31C52A85928D0C45C47762FA1FBDB5&guid=CDF0EFB91301874173DACC6DB5DB719F HTTP/1.1" 2744 "119.188.138.106" TCP_MISS:DIRECT cc.stream.qqmusic.qq.com "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.00; MP222)" audio/mpeg
要求尽快解决之,因为如果解决这个问题会导致缓存效果大幅提高。我确认的问题是,使用上面的动态url(必须完整带上vkey,guid,fromtag参数)可以下载,但是达不到缓存效果,因为url在动态变化。
二、问题分析
如何尽快解决该问题呢?
下面是我记录的解决这个问题的思路:
由上分析可见,这是一个防盗链url的缓存问题,并且我们当前开发的视频插件使不上,因为视频插件是结合前方导流服务器来进行的,所以我打算考虑ATS现有的插件工具,看能否解决该问题
下面假设ATS安装在/opt/ats目录下面
尝试一:使用remap rewrite url方法
如果这个方法能解决问题,将是最简单有效的方法。下面我们需要紧接着明确不带参数的url是否可以正常回源?
经过测试,发现对QQ音乐行不通,那么我们只能放弃。
下面我还是记录一下这个方法的使用过程,它使用的是regex_map方法,在remap.config中添加
map http://cc.stream.qqmusic.qq.com/ http://cc.stream.qqmusic.qq.com/ @plugin=regex_remap.so @pparam=/opt/ats/etc/trafficserver/maps.reg @pparam=profile @pparam=method
然后在当前目录下面新建一个maps.reg文件,添加
.* http://cc.stream.qqmusic.qq.com/$P
它的意思是,将所有连接中的?及之后的参数都去掉,只保留path部分,$P就是表示path部分。然后热加载配置文件
traffic_line -x
经过测试可行,参见参考文献[2]
这个问题我遇到的坑是,重写后的url无法访问,返回403 Forbidden错误,截图如下
尝试二:使用cacheurl模块方法
这是个不得已而为之的方法,能解决类似情况下的绝大多数问题,但是也有些缺陷(后面有说明)。使用方法如下:
在/opt/ats/libexec/trafficserver/目录下面添加配置cacheurl.config,在里面添加一条正则匹配规则
#cacheurl.config
http://cc.stream.qqmusic.qq.com/([^\?]+)\?vkey=([^/]+)$ http://cc.stream.qqmusic.qq.com.TSINTERNAL/$1
然后在plugin.config中添加动态库cacheurl.so,它已经默认安装在/opt/ats/libexec/trafficserver/目录下面
#plugin.config
cacheurl.so
然后热加载配置文件
traffic_line -x
我们将会在diags.log中看到配置文件生效,并重新加载动态库的日志信息。
注意:插件cacheurl.c代码中默认的配置文件为cacheurl.config,它的路径是/opt/ats/libexec/trafficserver/目录下面。
测试效果是可行的,但是遇到如下问题
1430190910.574 289 206 [11:15:10] 183.212.124.138 "GET http://cc.stream.qqmusic.qq.com/M500003QcQR43TAUTh.mp3?vkey=B15A9619000ECAF52964C9A72FDB31092ED446D82EAEBA470FD9BED36AB70583&guid=A33A004B07F6F04A098FC82039BAEE3D HTTP/1.1" 82618 "119.188.138.106" TCP_MISS:DIRECT cc.stream.qqmusic.qq.com "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.00; MP222)" audio/mpeg
1430190910.576 173 206 [11:15:10] 100.92.186.16 "GET http://cc.stream.qqmusic.qq.com/M500000HfRl84VaTDc.mp3?vkey=4D67ACFDCEAAD5A37BA5DC88C7B3555416D36DFE2C729CCF39FFD536BF477223&guid=37FC22405551ED9A5D4B62E09E200B1E HTTP/1.1" 17020 "119.188.138.106" TCP_MISS:DIRECT cc.stream.qqmusic.qq.com "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.00; MP222)" audio/mpeg
1430190910.576 181 206 [11:15:10] 112.21.228.183 "GET http://cc.stream.qqmusic.qq.com/M500004Fo3dp3eyNKs.mp3?vkey=FC4C91B6496669C9D8CFE0CBC56AA17F2A40CEE5AA54242424A88ED3C598238A&guid=033D4FE5F5B7EFB971042859332E1C8E HTTP/1.1" 17079 "119.188.138.106" TCP_MISS:DIRECT cc.stream.qqmusic.qq.com "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.00; MP222)" audio/mpeg
经过分析,发现是用户访问的url是错误的,上面给出的url中都不含fromtag=57参数,这将会被源站返回403 Forbidden响应,但是它会导致反复回源,如果是完整的url,是可以正常回源的。
解决的方法是,先补全url去获取资源并缓存,后续正确和不正确的url请求,都将正确命中,另外,如果可能,要先删除旧的错误缓存。下面是我的执行命令
curl -X PURGE -vx "127.0.0.1:8081" "http://cc.stream.qqmusic.qq.com/M500004Fo3dp3eyNKs.mp3?vkey=FC4C91B6496669C9D8CFE0CBC56AA17F2A40CEE5AA54242424A88ED3C598238A&guid=033D4FE5F5B7EFB971042859332E1C8E&fromtag=57"
curl -vx 127.0.0.1:8081 -o /dev/null "http://cc.stream.qqmusic.qq.com/M500004Fo3dp3eyNKs.mp3?vkey=FC4C91B6496669C9D8CFE0CBC56AA17F2A40CEE5AA54242424A88ED3C598238A&guid=033D4FE5F5B7EFB971042859332E1C8E&fromtag=57"
三、测试方法
检查cacheurl模块是否加载, 再验证正则规则是否生效?
curl -vx 127.0.0.1:8081 -o 463238.m4a "http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=EB9DCBE77D88ED0335E7566A9FA8A3681BA1A7AD4DB5545C48CDAD9610601132&guid=ffffffffbb69dc14fffffffffb7c39fa&fromtag=57"
多执行几次,看缓存状态码变化是否符合
http://blog.csdn.net/tao_627/article/details/45334177
中的描述规律?
再执行一个类似的链接
curl -vx 127.0.0.1:8081 -o 463238.m4a "http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=A3710A40FB1D1DC4A2D4ECB34DFFDFD63DAC8D5FEC53833D651DB9E0F4CBB346&guid=00000000327ec818ffffffffbfdeefc7&fromtag=57"
看是否已经缓存?
如果要清除缓存重来一遍,使用下面的命令清除
curl -X PURGE -vx "127.0.0.1:8081" "http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=EB9DCBE77D88ED0335E7566A9FA8A3681BA1A7AD4DB5545C48CDAD9610601132&guid=ffffffffbb69dc14fffffffffb7c39fa&fromtag=57"
curl -X PURGE -vx "127.0.0.1:8081" "http://cc.stream.qqmusic.qq.com/463238.m4a?vkey=A3710A40FB1D1DC4A2D4ECB34DFFDFD63DAC8D5FEC53833D651DB9E0F4CBB346&guid=00000000327ec818ffffffffbfdeefc7&fromtag=57"
然后重复上面的步骤。
四、需要澄清的几个问题
1.配置文件的热加载
经过测试,发现添加插件和配置文件后,不需要重启,只需要热加载配置文件就可以。
2.cacheurl模块会缓存错误的响应吗,比如上面的403响应?
经过阅读源码和实际测试,发现不会。
3.缓存内容的正则刷新
在CDN环境下,如果我们缓存的资源有更新怎么办?数量不大时,可以考虑手动或是脚本匹配更新,更好的方法是使用正则刷新插件,需要后续调研
4.records.config中pristine头中的0或是1都没有问题
五、再续一例
线上日志需要缓存如下带有防盗链的url:
1438157082.406 38 200 [16:04:42] 100.90.19.80 "GET http://click.hd.sohu.com.cn/r.gif?url=http%3A//tv.sohu.com/20141222/n407174469.shtml&refer=http%3A//tv.sohu.com/20141222/n407174465.shtml%3Ftxid%3D72b6b32533ae9786a2b937d2736efa18&fuid=13250766992031914142&yyid=B266892CA90AD50719C9BBC792D1E64C&passport=&sid=1112261906365278&pid=434&vid=2156332&cid=2&msg=impression&rec=0_2482560_101200101_2_44_0%2C1_2325944_101200101_2_44_0%2C2_2175399_101200101_2_44_0&ab=0&formwork=30&type=100&v=maybelike_2_v20130829&landing_refer=http%3A%2F%2Fkan.sogou.com%2Fdianshiju%2Flishi--1--%2F&fuuid=59b4b887-dc77-789c-258f-00000000014ed8d7904f139d&uuid=1438157089328 HTTP/1.1" 300 "220.181.90.94" TCP_MISS:DIRECT http://tv.sohu.com/20141222/n407174469.shtml "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" image/gif
1438157082.388 29 204 [16:04:42] 100.78.21.28 "GET http://click.hd.sohu.com.cn/ifox.gif?type=sc&expand1=4&expand2=6&expand3=78&_=1438157049&uid=11&LocalIp=192.168.1.130&MashCode=d8e84593f4d7a7ea5d0fa9264398a5aa&ChannelID=0&v=5.0.0×tamp=18446744073052556995&ost=4&osv=d8e84593f4d7a7ea5d0fa9264398a5aa&btea=bef6464d423cb12d55f50bf408d82002 HTTP/1.1" 152 "220.181.90.94" TCP_MISS:DIRECT - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)" -
解决办法:
在plugin.config中添加一行
cacheurl.so
在/opt/ats/libexec/trafficserver/中添加一个cacheurl.config文件,内容如下
http://click.hd.sohu.com.cn/([^\?]+)\?(.*) http://click.hd.sohu.com.cn.TSINTERNAL/$1
在cache.config中添加一行
dest_domain=. suffix=gif ttl-in-cache=10d
(如果在匹配规则合法,ATS没有报错的情况,还是无法缓存住,可以试试cache.config中的配置,这是实践中摸索出的经验)
六、preload脚本
为了减少回源量,提高缓存命中率,经过研究发现可以对该站点的mp3,m4a等音频文件做预加载缓存,脚本如下:
cat access.log | grep -v '127.0.0.1' | grep 'TCP_MISS' | awk -F '"' '{print $2}' | awk '{print $2}' | grep -v 'fromtag=' | grep -v '127.0.0.1' > miss_url.log
cat miss_url.log | sort | uniq -c | sort -nr | awk '{print $2}' > miss_preload.log
sed -i 's/$/\&fromtag=90/g' miss_preload.log
wget -SO /dev/null -e 'http_proxy=127.0.0.1:8081' -c --limit-rate=500k -i ./miss_preload.log
上述脚本的思想是:
先将access.log中含TCP_MISS和framtag=的那些日志过滤出来,然后去重排序,按照访问次数来由高到低排序,先处理次数多的url,使用wget限速下载去实现preload功能,以尽量减小对服务器的压力
七、参考文献
[1].http://trafficserver.apache.org/tools/via#cMsSf 缓存状态查询
[2].http://bbs.chinaunix.net/thread-3768941-1-1.html
[3].http://www.shencan.net/index.php/2013/10/15/ats-cacheurl%E6%8F%92%E4%BB%B6%E5%AE%9E%E6%88%98/ 灿哥cacheurl