从阿里云 oss 下载文件,文件居然损坏了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
工单节点使用指南
请用平和的语言准确描述你所遇到的问题
厂商的技术支持和你一样也是有喜怒哀乐的普通人类,尊重是相互的
如果是关于 V2EX 本身的问题反馈,请使用 反馈 节点
wty
V2EX    全球工单系统

从阿里云 oss 下载文件,文件居然损坏了

  •  
  •   wty 2020-09-14 01:36:28 +08:00 3528 次点击
    这是一创建于 1853 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前测出用 axel 多线程(开了 4 线程)下载会出现这种情况,chrome 和 ossutil 下载的没问题

    对比了一下文件内容,出错的文件后面有部分变成从头开始下载的了,并且不止从头开始了一次。最终下载下来的文件大小相同。

    另外手机 app 里面看见的文件大小居然是错的,疑似单位换算用了 1000 除。网页版里的倒是对的。

    (感觉实在是太扯淡了,这 bug 有点多啊。。。)

    8 条回复    2020-09-14 20:39:29 +08:00
    wtks1
        1
    wtks1  
       2020-09-14 04:22:55 +08:00 via Android
    用 aria2 的多线程试试?目前已知 axel 在下载某些链接的时候无法追踪多次跳转的地址,不知道是不是这个问题导致的
    whileFalse
        2
    whileFalse  
       2020-09-14 07:27:02 +08:00
    手机 app 是什么 app
    wty
        3
    wty  
    OP
       2020-09-14 08:48:45 +08:00 via Android
    @whileFalse 就是叫 阿里云 的那个 app
    abo321
        4
    abo321  
       2020-09-14 13:38:52 +08:00
    您好。感谢您使用 OSS 和反馈。

    针对这个问题,我们本地使用 axel 工具做了测试,版本为 2.16.1,os 为 ubuntu 。分别通过 axel 和 curl 对下载的数据做 md5 对比,其值都是一样的。

    具体的测试如下,

    ===================

    测试命令 axel -n 4 -o axel-download-2.data http://skyranch-02.oss-cn-hangzhou.aliyuncs.com/curl.zip 4 个线程同时下载。

    抓包后,看到一共有 5 个 Get 请求
    (1) GET /curl.zip Range: bytes=1- 返回 Content-Length: 330978 , 报文的数据只返回了差不多 0x446C 数据
    (2) GET /curl.zip bytes=165489-248233 返回 Content-Length: 82745 ,
    (3) GET /curl.zip 返回 Content-Length: 330979 , 报文的数据只返回了差不多 0x2958c ( 169556 ) 数据, 涵盖 0- 165489 范围
    (4) GET /curl.zip bytes=248234-330978 返回 Content-Length: 82745
    (5) GET /curl.zip bytes=82744-165488 返回 Content-Length: 82745

    测试文件长度为 330979,330979/4 = 82744.75 ,分段为 82745, 分别通过 axel 和 curl 对下载的数据做 md5 对比,其值都是一样的。

    大概推出,这个工具的做法:
    (1) 请求为获取到 文件的 大小。通过 ranget 1- 模式获取 文件大小 比 head object 更具有通用性
    (2) - (5) 为 多线程请求,正好有 4 个并发 请求,最开始的请求 通过非 range 方式请求,读数据时,只读 需要的部分。其它并发按照 分片大小请求。

    ===================

    想和您确认下,您使用的 axel 工具是什么版本, 测试文件的大小,以及 用到的 axel 是不是 同一个?

    再次感谢您的反馈!
    wty
        5
    wty  
    OP
       2020-09-14 15:39:33 +08:00
    @abo321 您好,我用的是 Axel 2.17.9, wsl2 里的 ubuntu2004

    我也试了一下 2.16.1 版本,是正常工作的,抓包发现请求不太一样,

    16 版本第一个请求 range 是 1- ,17 版本是 0- (这点似乎没有影响),17 版本的每个下载请求都有 range 参数。

    问题出在下载最后一个 part 上,对一个 336700 字节的文件,16 版本的 range 是 252527-336699,17 版本 280583-336700 (估计是代码写错了),oss 对于这种请求处理是忽略 range 项,从头开始读,返回 http200 。

    但是根据 RFC2616 138 页的说法,服务器应该是把大小限制到文件大小,而不是从头开始读。以下是原文:

    If the last-byte-pos value is absent, or if the value is greater than
    or equal to the current length of the entity-body, last-byte-pos is
    taken to be equal to one less than the current length of the entity-
    body in bytes.

    另外上面还提到一个手机 app 单位换算错误的问题,也麻烦转达一下,谢谢!
    abo321
        6
    abo321  
       2020-09-14 19:22:21 +08:00
    @wty 谢谢您的回复。请问下您使用的 app 是 Android 版还是 IOS 版?
    abo321
        7
    abo321  
       2020-09-14 20:04:44 +08:00
    @wty 关于 Range Get 的问,可以参考下我们的官网文章《如何通过 HTTP Range 请求分段获取 OSS 资源》: https://help.aliyun.com/knowledge_detail/39571.html

    可以通过增加请求头 x-oss-range-behavior:standard 来兼容 RFC 定义的行为。

    =================
    兼容行为
    使用 HTTP Range 时,增加请求头 x-oss-range-behavior:standard,可以改变指定范围不在有效区间时 OSS 的行为。行为改变的示例如下。

    注:此处假设 Object 资源大小为 1000 字节,Range 有效区间为 0-999 。

    Range: bytes=500-2000:末字节超出有效区间,返回 500-999 字节范围内容。
    Range: bytes=1000-2000:首字节超出有效区间,返回错误 416 (InvalidRange)。
    Range: bytes=1000-:首字节超出有效区间,返回错误 416 (InvalidRange)。
    Range: bytes=-2000:指定范围超出有效区间,返回 0-999 字节,即完整的文件内容。
    =================

    有任何问题,都可以在阿里云存储官网( https://www.aliyun.com/product/oss )钉钉扫描二维码找到我们!

    再次感谢您的反馈!我们会始终认真倾听各种反馈,并持续不断的改进产品,为用户提供更好的云存储服务!
    wty
        8
    wty  
    OP
       2020-09-14 20:39:29 +08:00 via Android
    @abo321 Android 版
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     881 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 20:37 PVG 04:37 LAX 13:37 JFK 16:37
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86