镜像回源

更新时间: 2025-09-08 21:08:36

当业务需要从自建源站或第三方云存储平滑迁移至阿里云对象存储(OSS)时,为避免因数据尚未完全迁移而导致的业务中断,可以配置镜像回源。配置后,当用户请求的文件在OSS中不存在时,OSS将自动从指定的源站获取该文件,在返回给用户的同时将其存储到OSS中。此功能确保了数据迁移期间所有数据的正常访问,实现业务的无缝过渡。

工作原理

镜像回源功能的核心是服务器端代理(Server-Side Proxy)。当客户端通过GET请求访问OSS中不存在的对象时,如果请求触发了预设的回源规则条件(如文件前缀匹配且返回HTTP 404错误),OSS服务器将自动向指定源站发起HTTP请求获取该文件。若源站返回200状态码,OSS会将文件内容返回给客户端,同时将文件存储到OSS中;若源站返回404或其他错误状态码,OSS则向客户端返回相应的错误信息。在此过程中,OSS充当代理角色,实现文件的按需迁移和一次性缓存。需要注意的是,文件一旦存储到OSS中,即使源站文件发生更新,OSS也不会自动同步更新。

image

从指定网站获取缺失文件

这是最基础的镜像回源配置场景,当用户访问OSS中不存在的文件时,系统会自动从指定的源站获取文件并存储到OSS中。以下示例演示如何配置从指定网站获取缺失文件:当访问examplebucketexamplefolder/目录下不存在的文件时,自动从https://example.com/获取文件。

步骤一:配置镜像回源规则

  1. 前往Bucket列表页面,然后单击目标Bucket名称。

  2. 在左侧导航栏,选择数据管理 > 镜像回源

  3. 镜像回源页面,单击创建规则

  4. 创建规则面板配置参数,未提及的参数保持默认即可。

    参数

    配置

    回源类型

    选择镜像

    回源条件

    勾选文件名前缀,在输入框中填写examplefolder/

    回源地址

    第一列(协议)选择 https,第二列(域名)填写 example.com,第三列(路径前缀)留空。路径前缀将拼接到域名后,构成回源URL的路径部分。

  5. 单击确定

步骤二:验证规则

  1. 访问https://examplebucket.oss-cn-hangzhou.aliyuncs.com/examplefolder/example.txt

  2. 如果examplebucket中不存在examplefolder/example.txt文件,则OSS向https://example.com/examplefolder/example.txt请求文件。

  3. 获取到目标文件后,OSS将文件重命名为examplefolder/example.txt后保存到examplebucket,并将文件返回给请求者。

回源时替换目录并校验文件完整性

在某些业务场景中,OSS中的目录结构与源站目录结构不同,同时需要确保回源文件的完整性。此场景演示如何在回源时进行目录映射,并通过MD5校验确保文件传输的可靠性:

  • 当请求者访问华东1(杭州)地域的bucket-01examplefolder目录不存在的文件时,可以从https://example.com站点的destfolder目录中获取文件。

  • 需要验证回源文件的MD5值,MD5值不匹配的文件不在bucket-01中保存。

步骤一:配置镜像回源规则

  1. 前往Bucket列表页面,然后单击目标Bucket名称。

  2. 在左侧导航栏,选择数据管理 > 镜像回源

  3. 镜像回源页面,单击创建规则

  4. 创建规则面板,按以下说明配置必要参数,其他参数保留默认配置。

    参数

    配置

    回源类型

    选中镜像

    回源条件

    选中文件名前缀,并设置为examplefolder/

    替换或截取前缀

    选中是否替换或截取前缀,并设置为destfolder/

    说明

    该选项仅在设置了回源条件中的文件名前缀后显示。

    回源地址

    第一列设置为https,第二列设置为example.com,第三列置空。

    检查MD5

    选中是否检查MD5。当回源请求的响应包含Content-MD5字段时,OSS会检查回源文件的MD5值与Content-MD5字段值是否匹配。

    • 匹配:客户端将获取文件,且OSS会保存回源文件。

    • 不匹配:由于计算MD5需要完整的文件数据,而此时文件已经透传回客户端,所以客户端能获取到文件,但OSS不会保存回源文件。

  5. 单击确定

步骤二:验证规则

  1. 访问https://bucket-01.oss-cn-hangzhou.aliyuncs.com/examplefolder/example.txt

  2. 如果bucket-01中不存在examplefolder/example.txt文件,则OSS向https://example.com/destfolder/example.txt请求文件。

  3. 获取到目标文件后,OSS进行以下操作:

    • 如果回源请求的响应包含Content-MD5字段,OSS会计算回源文件的MD5值,并与Content-MD5字段进行匹配。MD5匹配成功则将文件重命名为examplefolder/example.txt后保存到bucket-01,并将文件返回给请求者;匹配失败时仅返回文件给用户,不保存该文件到bucket-01

    • 如果回源请求的响应不包含Content-MD5字段,OSS将文件重命名为examplefolder/example.txt后保存到bucket-01,并将文件返回给请求者。

根据不同目录回源至不同站点

当业务涉及多个源站时,可以根据访问的目录路径将请求分发到不同的源站。此场景适用于多源站数据整合或分布式存储架构的迁移。例如有两个目录结构相同的源站:源站A(https://example.com)和源站B(https://example.org),需要实现以下场景:

  • 当请求者访问华北2(北京)地域的bucket-02/dir1目录中不存在的文件时,从https://example.com站点的example1目录中获取。

  • 当请求者访问bucket-02/dir2目录中不存在的文件时,从https://example.org站点的example2目录中获取。

  • 根据源站A和源站B是否设置重定向策略,决定是否向重定向指定的地址请求文件。

步骤一:配置镜像回源规则

  1. 前往Bucket列表页面,然后单击目标Bucket名称。

  2. 在左侧导航栏,选择数据管理 > 镜像回源

  3. 镜像回源页面,单击创建规则

  4. 创建规则面板,按以下说明配置两条镜像回源规则,其他参数保留默认配置。

    • 规则一

      参数

      配置

      回源类型

      选中镜像

      回源条件

      选中文件名前缀,并设置为dir1/

      替换或截取前缀

      选中是否替换或截取前缀,并设置为example1/

      说明

      该选项仅在设置了回源条件中的文件名前缀后显示。

      回源地址

      第一列设置为https,第二列设置为example.com,第三列置空。

      3xx请求响应策略

      选中跟随源站重定向请求

      说明

      未选中跟随源站重定向请求时,OSS会直接将源站重定向规则指定的地址返回给请求者。

    • 规则二

      参数

      配置

      回源类型

      选中镜像

      回源条件

      选中文件名前缀,并设置为dir2/

      替换或截取前缀

      选中是否替换或截取前缀,并设置为example2/

      说明

      该选项仅在设置了回源条件中的文件名前缀后显示。

      回源地址

      第一列设置为https,第二列设置为example.org,第三列置空。

      3xx请求响应策略

      选中跟随源站重定向请求

  5. 单击确定

步骤二:验证规则

  1. 访问https://bucket-02.oss-cn-beijing.aliyuncs.com/dir1/example.txt

  2. 如果bucket-02dir1目录中不存在example.txt文件,则OSS向https://example.com/example1/example.txt请求文件。

    • 如果源站A针对example1/example.txt设置了重定向规则,则OSS会向源站重定向规则指定的地址重新发起请求,获取到文件后会将文件命名为dir1/example1/example.txt保存至bucket-02,并返回给请求者。

    • 如果源站A未针对example1/example.txt设置重定向规则,则OSS获取到文件后会将文件命名为dir1/example1/example.txt保存至bucket-02,并返回给请求者。

  3. 如果请求者访问https://bucket-02.oss-cn-beijing.aliyuncs.com/dir2/example.txt,则通过镜像回源规则获取的文件将存储在bucket-02dir2/example2目录。

从私有Bucket获取并透传指定参数

当源站为OSS私有Bucket时,需要配置相应的访问权限,同时可能需要将请求中的特定参数传递给源站。此场景演示如何配置OSS私有源站回源并实现参数透传。如华东2(上海)地域有两个Bucket:bucket-03(公共读)和bucket-04(私有),需要实现以下场景:

  • 当请求者访问bucket-03根目录下examplefolder目录中不存在的文件时,从bucket-04examplefolder目录中获取目标文件。

  • 允许将请求URL中携带的query string传递到源站。

  • 允许将请求URL中携带的header1header2header3三个HTTP header传递到源站。

步骤一:配置镜像回源规则

  1. 前往Bucket列表页面,然后单击目标Bucket名称。

  2. 在左侧导航栏,选择数据管理 > 镜像回源

  3. 镜像回源页面,单击创建规则

  4. 创建规则面板,按以下说明配置必要参数,其他参数保留默认配置。

    参数

    配置

    回源类型

    选中镜像

    回源条件

    选中文件名前缀,并设置为examplefolder/

    源站类型

    选中回源OSS私有Bucket,并在回源Bucket下拉列表选择bucket-04

    配置该选项后,当用户访问不存在的对象时,OSS会通过默认角色AliyunOSSMirrorDefaultRole从指定源站私有Bucket中获取数据。数据获取过程中需要具备AliyunOSSReadOnlyAccess权限,该权限用于确保OSS只能以只读方式访问源站数据,避免对源站数据进行修改或删除。

    RAM用户配置镜像回源OSS私有Bucket时,必须拥有ram:GetRole权限,该权限用于检查AliyunOSSMirrorDefaultRole角色是否存在。

    • 如果存在,则直接调用该角色。

    • 如果不存在,建议通过RAM用户关联的阿里云账号预先创建AliyunOSSMirrorDefaultRole角色并授予该角色AliyunOSSReadOnlyAccess权限,避免授予RAM用户高风险权限,如创建角色(ram:CreateRole)和为角色授权(ram:AttachPolicyToRole)。授权完成后,RAM用户可直接复用已创建的角色,降低权限配置风险。

    回源地址

    第一列设置为https,其他置空。

    回源参数

    选中携带请求字符串

    OSS会将URL请求中的query string传递到源站。

    设置HTTP header传递规则

    选中传递指定HTTP header参数,并添加header1header2header3三个HTTP header。回源规则不支持传递部分标准HTTP header,例如authorizationauthorization2rangecontent-lengthdate等,以及以x-oss-oss-x-drs-开头的HTTP header。

    重要

    回源私有Bucket时,请勿选择传递所有HTTP header参数,否则会导致回源失败。

  5. 单击确定

步骤二:验证规则

  1. 访问https://bucket-03.oss-cn-shanghai.aliyuncs.com/examplefolder/example.png?caller=lucas&production=oss

  2. 如果bucket-03中不存在examplefolder/example.png文件,则OSS会向https://bucket-04.oss-cn-shanghai.aliyuncs.com/examplefolder/example.png?caller=lucas&production=oss请求文件。

  3. bucket-04会根据传递的?caller=lucas&production=oss参数,将example.png返回给OSS。

  4. OSS会将获取的文件命名为examplefolder/example.png,并将命名后的文件存储至bucket-03

如果请求中还携带了header1header2header3的HTTP header时,也会被传递到bucket-04

应用于生产环境

数据无缝迁移

迁移方案详情请参见结合镜像回源将业务无缝迁移至阿里云OSS

刷新已回源对象

由于镜像回源是一次性缓存机制,源站上的同名文件更新后,OSS不会自动刷新或重新获取该对象。可以通过以下方式强制刷新已存储到OSS中的对象。

  • 手动删除:通过控制台或API删除OSS中的对象,下次访问时将重新触发回源。

  • 生命周期规则:为镜像回源的对象配置过期策略,使其在固定时间后自动删除,实现定期刷新。

  • 文件名版本化:在源站更新文件时使用新的名称(如 style.v2.css),从根本上避免缓存问题,这是推荐的做法。

风险防范与容错

  • 源站压力:确保源站有足够的带宽和处理能力应对回源请求。在迁移初期,回源请求量可能较大,建议监控源站负载,并考虑在业务低峰期进行数据预热。

  • 成本控制:为避免意外的高额费用,建议在阿里云费用管理中心设置费用预警,监控与回源相关的请求量。

  • 安全配置:确保源站可以被OSS访问,如果回源地址使用HTTPS协议,请确保源站证书由受信任的CA签发、域名匹配且未过期。

  • 日志查询:通过实时日志查询功能查看回源相关日志,回源请求的User-Agent包含aliyun-oss-mirror字样。

配额与限制

  • 规则数量与顺序:每个Bucket最多可配置20条回源规则。规则按RuleNumber从小到大的顺序进行匹配,一旦命中一条规则,后续规则将不再匹配。可以通过规则右侧的上移下移操作调整匹配优先级。

  • QPS和流量

    • 中国内地各地域:默认总QPS为2000,总带宽为2 Gbit/s。

    • 非中国内地各地域:默认总QPS为1000,总带宽为1 Gbit/s。

    • 此限制为单个阿里云账号在对应区域所有Bucket的镜像回源能力总和,超过限制后请求会被限流,返回503错误。如需更高配额,请联系技术支持

  • 源站地址:必须是可通过公网访问的域名或IP地址,且符合RFC3986编码规范,不支持内网地址

  • 超时时间:镜像回源默认超时时间为10秒。

计费说明

使用过程中产生的 OSS 请求和流量将按 OSS 标准用量计费,详情请参见OSS计费概述

常见问题

镜像回源文件大小与源站文件大小不一致?

如果镜像回源文件大小与源站文件大小不一致,可以按照以下步骤进行排查。

  1. 检查镜像回源文件和源站文件的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校验值。

  2. 比较镜像回源文件和源文件的MD5或CRC64校验值。

    # -*- coding: utf-8 -*-
    import oss2
    import hashlib
    import requests
    # 如果需要比较CRC64,由于Python标准库不支持CRC64,可以使用第三方库如crcmod
    # 安装crcmod:pip install crcmod
    import crcmod
    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_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校验值不一致,表明这两个文件的内容并不相同。需要继续下一步,检查是否存在特殊请求头。

  3. 检查特殊请求头。

    screenshot_2025-02-18_17-04-03

    • 检查镜像回源请求中是否包含特殊的HTTP请求头部,例如Accept-Encoding: gzip, deflate, br,该头部表示客户端能够接受压缩格式的数据。

    • 如果镜像回源请求使用了HTTP压缩逻辑,并且请求的文件满足压缩条件,也会导致这两个文件大小不一致。

    • 如果存在Accept-Encoding头部,需要禁止传递该头部。

      • 如果设置了允许传递所有HTTP header,需要在禁止传递指定HTTP header中指定accept-encoding。

        p917892

      • 如果设置了传递指定HTTP header,确保指定的header中不包含accept-encoding。

        screenshot_2025-02-19_14-30-45

回源失败如何排查?

遇到回源失败(如返回 424 MirrorFailed 错误)时,可按以下步骤排查。

  1. 检查源站可达性。

    # 将URL替换为您的实际源站地址和文件路径
    curl -I "https://www.example.com/images/test.jpg"
  2. 检查DNS解析。

    # 请将域名替换为实际源站域名
    nslookup www.example.com
  3. 检查HTTPS证书(如果源站是HTTPS)。

    # 请将域名替换为实际源站域名
    openssl s_client -connect www.example.com:443 -servername www.example.com
  4. 通过OSS的实时日志查询进行问题分析。

为什么没有生成镜像回源文件?

客户端发起HEAD请求来获取文件元数据时,仅获取文件的基本信息(如大小、类型等),并不下载实际的文件内容。HEAD请求不会触发镜像回源规则从源站请求文件并写入OSS目标Bucket。

镜像回源返回非预期状态码?

当请求触发镜像回源时,如果源站返回的状态码不是404、200或者206,需要具体分析源站的响应情况。

  • 源站为OSS:需要检查以下配置项。

    • 禁止传递指定HTTP header参数:禁止传递host头部用于避免暴露源站信息,同时确保回源请求能按照预期正确处理。如果不配置禁止传递host,则回源请求会透传目标Bucket的host值到源站。由于每个Bucket的host值是唯一的,如果请求的host与源站的实际host不匹配,源站会返回403错误,然后OSS会向客户端返回424错误,表示由于源站未能成功处理请求导致操作失败。

      screenshot_2025-02-19_14-31-42

    • 回源OSS私有Bucket:如果未配置权限,请确认目标Bucket及其Object的ACL权限是否设置为公共读。如果已配置权限,请确认用于镜像回源的角色授权策略是否发生变更,导致权限不足。镜像回源默认使用的角色为AliyunOSSMirrorDefaultRole,该角色的默认系统策略是AliyunOSSReadOnlyAccess

  • 源站不是OSS:结合服务侧的日志,检查携带SNI(服务器名称指示)、回源参数、header传递等配置,以分析具体的源站异常原因。源站可能会返回401(未授权)、403(禁止访问)、5xx(服务器内部错误)等状态码。

回源规则的匹配顺序是怎样的?

按规则编号(RuleNumber)从小到大进行匹配。命中第一条满足条件的规则后,立即执行该规则并停止匹配后续规则。

可以回源到VPC内的服务或内网IP吗?

不可以。源站必须拥有一个可公网访问的地址,如需访问VPC内的服务,请通过NAT网关或公网SLB将其暴露到公网。

源站文件更新后,OSS中的文件为什么没有更新?

镜像回源是一次性拉取机制,不会自动同步源站的更新。需要手动删除OSS上的回源文件,或采用文件名版本化的策略来获取新文件。

上一篇: 回源配置 下一篇: 重定向
阿里云首页 对象存储 相关技术圈