作者:张医博

浅谈

很多 oss 使用者在使用 Python SDK 时出现很多问题,不确定是否影响使用,有的安装失败环境有问题,今天说下遇到的几个案例

官方安装

pip install oss2

版本最好是 2.7.5 或以上

oss2 依赖

如果要开启 crc64 循环冗余校验,需要先将 crcmod 安装好。

安装 python-devel 执行 yum install python-devel。

需要循环冗余校验,安装 crcmod 执行 pip install crcmod。

安装遇到的问题

验证 oss2

先判断是 oss2 是否安装成功,在命令行输入python并回车,进入Python环境,执行以下命令检查SDK版本:

>>> import oss2

>>> oss2.__version__

'2.x.x'

导入 crcmod 失败

>>> import crcmod._crcfunext

Traceback (most recent call last):

File "", line 1, in

ImportError: No module named _crcfunext

没有安装 python-devel 或者 crcmod ,如果已经安装 crcmod ,请 uninstall 后,重新安装 python-devel 然后再安装 crcmod。

crcmod 安装的环境 path 和你本机的 python 环境不一致,可以用 sys path 查看你 python 加载的环境变量路径确认一下。

参考一些网上的处理方法,这是个开源的报错 参考

使用遇到问题排查

问:同台机器 ossutil 很快,python SDK 很慢

ossutil 源码是 go ,并发上传的性能确实很好,但是 python SDK 也至于慢很多,一般这种情况基本都是默认开启了 crc64 。

如果对性能有要求的话,建议把 crc64 关掉,通过在 header 头中增加 Content-md5 头的方式替代 crc64 更好。

= oss2.Auth('AK', 'SK')

= oss2.Bucket(auth, 'endpoint', 'bucket',enable_crc=False)


问:安装 oss2 导入出现 urllib3 不存在提示


答:

和之前说过的一样,这种错误都是 python 自身的问题,看哪个依赖的模块没有,安装即可, oss2 的 http 请求处理依赖 urllib3 。

确认下 pip install 安装的环境和本地 python 环境是否一致。

问:OSS python SDK 分片上传失败


用户通过 python SDK 的分片上传函数上传到 OSS 失败,碎片管理中出现很对碎片。

先确认是直接传到 OSS,还是通过其他 proxy 传输到 OSS (类似 CDN),如果经过 CDN 再上传到 OSS 需要在 OSS 上配置跨域的头,Access-Control-Allow-Origin 、Access-Control-Allow-Mehtod 、Access-Control-Allow-header,并且将 Etag 暴露出去。

客户端上传失败是因为网络超时,还是捕获到异常上传失败,需要详细看下捕获到的 SDK 异常信息分析,如果是网络超时导致上传失败,建议使用断点续传来替代普通上传。断点续传支持分片,并发,已经弱网的兼容。

清理掉上传失败的碎片文件重新上传。

当以上操作都解决不了你的问题时,需要提供以下信息升级阿里云便于快速定位:

提供 SDK 异常时返回的 requestID,这个属性是 response header 中携带的记录了完整的 OSS 请求过程。

客户端部署 tcpdump ,然后重新运行代码上传,保存抓包。

tcpdump -i -s0 host -w faild.pcap

案例:

Centos 机器上执行分片上传 SDK 问题正常,但是 ubuntu 机器上传总是报 403 失败。

分析:

首先出现问题后,如果在 ubuntu 机器上,操作 OSS 出现 403 ,OSS 服务端会返回 403 对应的 OSS requestID,里面包含了 403 的原因,需要提供给阿里云排查。

客户端部署 tcpdump 抓包,可以通过 tcp 报文排查是否由于 header 头信息不对引起的计算签名与服务端不匹配。

POST /ttsservice%2Fpasswd?uploadId=D468E486D1D94D90A1AB8885A4E32AE0 HTTP/1.1

Host: rokid.oss-cn-hangzhou.aliyuncs.com

Accept-Encoding: identity

Accept: */*

Content-Length: 137

date: Sat, 29 Dec 2018 07:32:34 GMT

authorization: OSS LTAIknFr:r2KPR0y4E0G5tnU/MYdcvXHPQQ4=

Content-Type: application/x-www-form-urlencoded

User-Agent: aliyun-sdk-python/2.6.0(Linux/4.4.0-31-generic/x86_64;3.4.3)

1"3195544E19D99658706D51EF5"HTTP/1.1 403 Forbidden

Server: AliyunOSS

Date: Sat, 29 Dec 2018 07:33:43 GMT

Content-Type: application/xml

Content-Length: 1122

Connection: keep-alive

x-oss-request-id: 5C2723573183A12D

x-oss-server-time: 0

SignatureDoesNotMatch

The request signature we calculated does not match the signature you provided. Check your key and signing method.

5C2723573183A12D

rokid.oss-cn-hangzhou.aliyuncs.com

LTAIknFr

r2KPR0y4E0G5tnU/MYdcvXHPQQ4=

POST

application/x-www-form-urlencoded

Sat, 29 Dec 2018 07:32:34 GMT

/rokid/ttsservice/passwd?uploadId=D468E486D1D94D90A1AB8885A4E32AE0

50 4F 53 54 0A 0A 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 77 77 77 2D 66 6F 72 6D 2D 75 72 6C 65 6E 63 6F 64 65 64 0A 53 61 74 2C 20 32 39 20 44 65 63 20 32 30 31 38 20 30 37 3A 33 32 3A 33 34 20 47 4D 54 0A 2F 72 6F 6B 69 64 2D 6F 70 73 2D 6D 6F 64 65 6C 2F 74 74 73 73 65 72 76 69 63 65 2F 70 61 73 73 77 64 3F 75 70 6C 6F 61 64 49 64 3D 44 34 36 38 45 34 38 36 44 31 44 39 34 44 39 30 41 31 41 42 38 38 38 35 41 34 45 33 32 41 45 30

如上是客户端抓到的报文信息,我们主要是分析请求头的信息。拿到请求后,带入到以下脚本中,看下计算出来的结果是否和 SDK 一致。如果一致说明 SDK 的计算是正确的,那么如果服务端收到的和客户端计算的 signature 还不一致说明请求的内容可能被网络中设备改动过,可以使用 https 的方式上传。

import base64

import hmac

import sha

mac = hmac.new("","POST\n\napplication/x-www-form-urlencoded\nSat, 29 Dec 2018 07:32:34 GMT\n/rokid/ttsservice/passwd?uploadId=D468E486D1D94D90A1AB8885A4E32AE0", sha)

Signature = base64.b64encode(mac.digest())

print(Signature)

如果抓包中和脚本中计算的结果不一致,有可能存在 SDK 在 ubuntu 平台编译的适配问题导致 MD5 值不一样。