一个关于nginx和其mp4模块的一个很奇怪的bug,求大神

龙千寻 发布于 2016/11/23 10:17
阅读 813
收藏 1

小弟遇到一个很奇怪的bug,因为对nginx没有那么熟悉,在看了一段时间源码和上网搜索后还是没有头绪,希望有遇到类似情况的朋友,nginx大神帮忙解答一下,感谢感谢~~~

首先是应用场景,nginx做http服务器,提供最简单的媒体下载服务,在我这里所有媒体均为视频,格式为mp4,nginx打开了MP4模块,首先由于某种需求,我每次去下载mp4时,会根据mp4文件的长度,将其分块,块大小为512kB(524288Byte),每一块做一次单独的http请求,相当于去做http range请求,这在大家通常的认知里,是不会有问题的,因为我只是分了块,每一块的range都没问题,最后我还一样会得到一个完整的MP4。

现在现象是,随机不定,可能会出现在请求某一块时,服务器端给我返回的数据不对,首先在nginx服务端,观察nginx log,我的url和range都完全没有问题,http状态码也是206,但是其中有一个参数输出没有达到预期,$body_bytes_sent 这个变量,预期中应该就等于range的长度(524288),但是出问题的时候,这个值大概就是12XXX。其次在客户端观察nginx给我返回的数据,我确实拿到了想要的range长度(524288),并不是只拿到了12XXX字节,但是我拿到的数据有误,确切说,有偏移,比如我想请求range:1024-2048,但实际我拿到数据后和源数据作比对,我拿到了源数据中从1224开始的数据,数据偏移了,以上是我举得例子,在实际情况中,我拿到的错误数据的偏移和我想要拿到数据得偏移之差,是一个定值178Byte

再来说说这个178Byte,首先nginx mp4模块中,有一段逻辑,就是当请求的url中包含start属性时,会重新mux mp4头,相当于重新生成了一个mp4文件,因为我的原始mp4文件中,有几个无用的mp4box,elts,udat等,nginx重新mux的时候,没有处理它们,相当于把我这些box丢弃掉了,所以,如果url中包含start时,重新生成的mp4头就会比我原始的MP4头少了178字节,但是首先我请求时,绝对不会加入start这个属性,源码中的逻辑也很简单,不带start,nginx就不会重新mux mp4头。所以头痛的问题就是,我明明没有带start属性,只是分块做了range请求,但是nginx有时候却会给我返回,看似很像是mux过mp4头之后的数据,因为他们之间永远偏移差178Byte

因为这个问题还不是必先,自己测试很难测出,所以才求助大神们!

加载中
返回顶部
顶部