本文介绍使用OSS镜像回源功能的常见问题和排查方法。
镜像回源文件大小与源站文件大小不一致?
如果镜像回源文件大小与源站文件大小不一致,可以按照以下步骤进行排查。
检查镜像回源文件和源站文件的
Last-Modified
时间戳。import oss2 import requests from datetime import datetime from oss2.credentials import EnvironmentVariableCredentialsProvider # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数 region = "cn-hangzhou" # yourBucketName填写配置镜像回源规则的Bucket名称。 bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # 填写镜像回源文件的完整路径。 object_key = 'yourObjectKey' # 填写源站文件的完整路径。 source_url = 'yourSourceUrl' # 获取镜像回源文件的Last-Modified时间戳 oss_object_info = bucket.get_object_meta(object_key) oss_last_modified = oss_object_info.headers['last-modified'] print(f"OSS Last-Modified: {oss_last_modified}") # 获取源站文件的Last-Modified时间戳。 response = requests.head(source_url) source_last_modified = response.headers.get('last-modified') print(f"Source Last-Modified: {source_last_modified}") # 将字符串格式的时间戳转换为datetime对象以便比较。 oss_time = datetime.strptime(oss_last_modified, '%a, %d %b %Y %H:%M:%S %Z') source_time = datetime.strptime(source_last_modified, '%a, %d %b %Y %H:%M:%S %Z') if oss_time < source_time: print("源站文件更新了") elif oss_time > source_time: print("镜像回源文件较新") else: print("两个文件的时间戳一致")
如果源文件的
Last-Modified
时间戳 > 镜像回源文件的Last-Modified
时间戳,表明镜像回源文件生成之后,源文件可能更新过。OSS从源站获取文件并写入目标Bucket时,不会保留源文件的
Last-Modified
时间戳(即源文件最后一次修改的时间)。相反,OSS会将镜像回源文件的Last-Modified
时间戳设置为该文件通过镜像回源功能被创建或更新到OSS上的时间。如果源文件的
Last-Modified
时间戳 ≤ 镜像回源文件的Last-Modified
时间戳,表明镜像回源文件生成之后,源文件没有更新。需要继续下一步,检查两者的MD5或CRC64校验值。
比较镜像回源文件和源文件的MD5或CRC64校验值。
# -*- coding: utf-8 -*- import oss2 import hashlib import requests from oss2.credentials import EnvironmentVariableCredentialsProvider # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数 region = "cn-hangzhou" # yourBucketName填写配置镜像回源规则的Bucket名称。 bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # 填写镜像回源文件的完整路径。 object_key = 'yourObjectKey' # 填写源站文件的完整路径。 source_url = 'yourSourceUrl' # 获取镜像回源文件的元数据。 oss_object_info = bucket.get_object_meta(object_key) oss_md5 = oss_object_info.headers.get('etag', '').strip('"') # ETag通常为MD5 oss_crc64 = oss_object_info.headers.get('x-oss-hash-crc64ecma', '') print(f"OSS MD5: {oss_md5}") print(f"OSS CRC64: {oss_crc64}") # 获取源站文件的内容并计算MD5和CRC64。 response = requests.get(source_url) if response.status_code == 200: source_content = response.content source_md5 = hashlib.md5(source_content).hexdigest() print(f"Source MD5: {source_md5}") # 如果需要比较CRC64,由于Python标准库不支持CRC64,可以使用第三方库如`crcmod` # 安装crcmod:pip install crcmod import crcmod crc64_func = crcmod.predefined.mkCrcFun('crc-64') source_crc64 = hex(crc64_func(source_content))[2:].upper().zfill(16) # 转换为16进制字符串并格式化 print(f"Source CRC64: {source_crc64}") # 比较MD5值。 if oss_md5 == source_md5: print("MD5校验值一致") else: print("MD5校验值不一致") # 比较CRC64值。 if oss_crc64.upper() == source_crc64: print("CRC64校验值一致") else: print("CRC64校验值不一致") else: print(f"Failed to fetch source file. HTTP Status Code: {response.status_code}")
如果两者的MD5或CRC64校验值一致,表明这两个文件内容相同。这种情况下,这两个文件的大小是一致的。
如果两者的MD5或CRC64校验值不一致,表明这两个文件的内容并不相同。需要继续下一步,检查是否存在特殊请求头。
检查特殊请求头。
检查镜像回源请求中是否包含特殊的HTTP请求头部,例如
Accept-Encoding: gzip, deflate, br
,该头部表示客户端能够接受压缩格式的数据。如果镜像回源请求使用了HTTP压缩逻辑,并且请求的文件满足压缩条件,也会导致这两个文件大小不一致。
如果存在
Accept-Encoding
头部,需要禁止传递该头部。如果设置了允许传递所有HTTP header,需要在禁止传递指定HTTP header中指定accept-encoding。
如果设置了传递指定HTTP header,确保指定的header中不包含accept-encoding。
没有生成镜像回源文件?
HEAD请求
客户端发起HEAD请求来获取文件元数据,但是不下载实际文件内容。HEAD请求仅用于获取文件的基本信息(如大小、类型等),并不会触发镜像回源规则到源站请求写入OSS 目标Bucket。
镜像回源返回非预期状态码
当请求触发镜像回源时,如果源站返回的状态码不是404、 200或者206,需要具体分析源站的响应情况。
源站为OSS
如果源站为OSS,需要检查以下配置项。
禁止传递指定HTTP header参数
禁止传递host头:host头用于避免暴露源站信息的同时确保回源请求能按照预期正确处理。如果不配置禁止传递host,则回源请求会透传目标Bucket的host值到源站。由于每个Bucket的host值是唯一的,如果请求的host与源站的实际host不匹配,源站会返回403错误(
403 from mirror host
),然后OSS会向客户端返回424错误,表示由于源站未能成功处理请求导致操作失败。回源OSS私有Bucket:
未配置:确认目标Bucket及其Object的ACL权限是否设置为公共读。如果都不是公共读,说明对目标Bucket下的Object没有访问权限,此时源站会返回403错误。
已配置:确认使用的镜像回源的角色授权策略是否变更,导致权限不足。默认使用的角色为
AliyunOSSMirrorDefaultRole
,该角色的默认系统策略是AliyunOSSReadOnlyAccess
。
源站不是OSS
结合服务侧的日志,检查携带SNI(服务器名称指示)、回源参数、header传递等配置,以分析具体的源站异常原因。源站可能会返回401(未授权)、403(禁止访问)、5xx(服务器内部错误)等状态码。
- 本页导读 (1)
- 镜像回源文件大小与源站文件大小不一致?
- 没有生成镜像回源文件?
- 镜像回源返回非预期状态码