OSS Python SDK

作者:張醫博

淺談

很多 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 "<stdin>", line 1, in <module>
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 更好。
  1. = oss2.Auth('AK', 'SK')
  2. = oss2.Bucket(auth, 'endpoint', 'bucket',enable_crc=False)

image.png

問:安裝 oss2 導入出現 urllib3 不存在提示

image.png

答:

  • 和之前說過的一樣,這種錯誤都是 python 自身的問題,看哪個依賴的模塊沒有,安裝即可, oss2 的 http 請求處理依賴 urllib3 。
  • 確認下 pip install 安裝的環境和本地 python 環境是否一致。

問:OSS python SDK 分片上傳失敗

image.png

用戶通過 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 <訪問oss的域名> -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)

<CompleteMultipartUpload><Part><PartNumber>1</PartNumber><ETag>"3195544E19D99658706D51EF5"</ETag></Part></CompleteMultipartUpload>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

<?xml version="1.0" encoding="UTF-8"?>
<Error>
 <Code>SignatureDoesNotMatch</Code>
 <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
 <RequestId> 5C2723573183A12D </RequestId>
 <HostId>rokid.oss-cn-hangzhou.aliyuncs.com</HostId>
 <OSSAccessKeyId> LTAIknFr </OSSAccessKeyId>
 <SignatureProvided>r2KPR0y4E0G5tnU/MYdcvXHPQQ4=</SignatureProvided>
 <StringToSign>POST
application/x-www-form-urlencoded
Sat, 29 Dec 2018 07:32:34 GMT
/rokid/ttsservice/passwd?uploadId=D468E486D1D94D90A1AB8885A4E32AE0</StringToSign>
 <StringToSignBytes>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 </StringToSignBytes>
</Error>
  • 如上是客戶端抓到的報文信息,我們主要是分析請求頭的信息。拿到請求後,帶入到以下腳本中,看下計算出來的結果是否和 SDK 一致。如果一致說明 SDK 的計算是正確的,那麼如果服務端收到的和客戶端計算的 signature 還不一致說明請求的內容可能被網絡中設備改動過,可以使用 https 的方式上傳。
import base64
import hmac
import sha
mac = hmac.new("<Secretkey>","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 值不一樣。

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top