配置了镜像回源规则后,当请求者访问Bucket中一个不存在的文件(Object)时,OSS会向回源规则指定的源站获取这个文件。在获取到目标文件后,OSS会将文件返回给请求者并存入Bucket。

使用限制

  • 规则数量

    回源规则最多配置20条,按RuleNumber的先后顺序依次匹配。如果命中当前规则,则后续规则不再匹配。规则未命中表示没有匹配回源条件,与回源后是否成功获取目标文件无关。

  • QPS和流量限制

    中国各地域默认QPS为2000、流量为2 Gbit/s;海外各地域默认QPS为1000、流量为1 Gbit/s。

  • 回源地址

    回源地址不支持内网地址。回源地址中支持增加图片处理参数,但不支持增加视频截帧参数。

  • 默认超时时间

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

使用场景

镜像回源主要用于数据无缝迁移到OSS的场景。例如某服务已经在自己建立的源站或者在其他云产品上运行。现因业务发展,需要将数据迁移到OSS上,但是又不能停止服务,此时可以在迁移数据的同时,使用镜像回源功能保证业务的正常进行。关于使用案例的更多信息,请参见互联网公司业务无缝迁移至阿里云OSS

使用流程

镜像回源具体流程如下图所示。

回源规则

  • 回源规则触发条件

    只有当GetObject本应该返回404的情况下,OSS才会执行镜像回源,向源站请求文件。

  • 回源文件命名规则

    OSS向源站请求的URL为http(s)://MirrorURL/ObjectName,回源到OSS的文件名为ObjectName。例如某Bucket设置的回源地址为https://aliyun.com,某用户请求的文件example.jpg不在该Bucket中。则OSS会通过https://aliyun.com/example.jpg获取文件,存储到OSS的文件名为example.jpg

  • 回源请求失败返回规则

    如果镜像源也不存在此文件,即镜像源返回给OSS的HTTP状态码为404,那么OSS也会返回404给用户。如果是其他非200的状态码(包括因为网络原因等获取不到文件的错误情况),OSS将返回424 MirrorFailed给用户。

  • x-oss-tag响应头

    通过镜像回源的文件会添加一个x-oss-tag响应头,值为MIRROR。格式为x-oss-tag:MIRROR

    文件回源到OSS后,只要文件不被覆盖,每次下载这个文件都会添加这个头部,用于表示这个文件来源于镜像回源。

  • 回源文件更新规则

    若某个文件已经通过镜像回源到OSS,源站的源文件发生了变化,OSS不会更新该文件。

  • 回源文件元信息
    OSS会将源站返回的以下HTTP头存为OSS文件的元信息:
    Content-Type
    Content-Encoding
    Content-Disposition
    Cache-Control
    Expires
    Content-Language
    Access-Control-Allow-Origin
  • HTTP请求规则
    • 传给OSS的Header信息不会传递给源站,QueryString信息是否会传递给源站取决于回源规则中的配置。
    • 如果源站是chunked编码返回,那么OSS返回给用户的也是chunked编码。

使用OSS控制台

通过控制台配置多条回源规则时,默认按规则创建时间的先后顺序依次匹配。如果您希望自定义规则匹配顺序,请通过规则右侧的上移下移操作来实现。

3

当请求者访问目标Bucket中不存在的文件时,可以通过指定回源条件和回源地址,从源站中获取目标文件。例如您在华东1(杭州)有名为examplebucket的Bucket,您希望请求者访问Bucket根目录下examplefolder目录中不存在的文件时,可以从https://www.example.com/站点的examplefolder目录获取目标文件。配置步骤如下:

  1. 登录OSS管理控制台
  2. 单击Bucket列表,然后单击目标Bucket名称。
  3. 在左侧导航栏,选择基础设置 > 镜像回源
  4. 单击设置,然后单击创建规则
  5. 创建规则面板,按以下说明配置必要参数,其他参数保留默认配置。
    参数 配置
    回源类型 选中镜像
    回源条件 选中文件名前缀,并设置为examplefolder/
    说明 配置单条回源规则时文件名前缀和后缀可选填;配置多条回源规则时,必须设置不同的文件名前缀或后缀区分不同的回源规则。
    回源地址 第一列设置为https,第二列设置为www.example.com,第三列设置为examplefolder
  6. 单击确定
    规则配置完成后的访问流程如下:
    1. 请求者首次访问https://examplebucket.oss-cn-hangzhou.aliyuncs.com/examplefolder/example.txt
    2. 如果examplebucket中不存在examplefolder/example.txt文件,则OSS向https://www.example.com/examplefolder/example.txt发起请求。
    3. 如果获取到目标文件,OSS将example.txt存入examplebucket的examplefolder目录,并将文件返回给请求者;如果未获取到文件,则返回404错误给请求者。

以上配置步骤仅满足镜像回源的基础应用场景,如果您需要配置其他镜像回源规则以满足特定的应用场景时,请参见镜像回源配置示例

使用阿里云SDK

以下仅列举常见SDK的配置镜像回源规则的代码示例。关于其他SDK的配置镜像回源规则代码示例,请参见SDK简介

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.RoutingRule;
import com.aliyun.oss.model.SetBucketWebsiteRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            SetBucketWebsiteRequest request = new SetBucketWebsiteRequest(bucketName);
            // 设置默认主页后,访问以非正斜线(/)结尾的Object,且该Object不存在时的行为。
            //request.setSubDirType(null);
            // 指定访问子目录时,是否支持转到子目录下的默认主页。
            //request.setSupportSubDir(false);

            List<RoutingRule> routingRules = new ArrayList<RoutingRule>();

            RoutingRule rule = new RoutingRule();
            rule.setNumber(1);
            // 只有匹配此前缀的Object才能匹配此规则。
            rule.getCondition().setKeyPrefixEquals("examplebucket");
            // 访问指定Object时,返回status 404才能匹配此规则。
            rule.getCondition().setHttpErrorCodeReturnedEquals(404);
            // 指定跳转的类型。
            rule.getRedirect().setRedirectType(RoutingRule.RedirectType.Mirror);
            // 指定镜像回源的源站地址。例如https://www.example.com/。
            rule.getRedirect().setMirrorURL("<yourMirrorURL>");
            //rule.getRedirect().setMirrorRole("AliyunOSSMirrorDefaultRole");
            // 指定执行跳转或者镜像回源规则时,是否携带请求参数。
            rule.getRedirect().setPassQueryString(true);
            // 与PassQueryString作用相同,优先级高于PassQueryString。只有设置RedirectType为Mirror时生效。
            rule.getRedirect().setMirrorPassQueryString(true);
            // 指定跳转时返回的状态码。只有设置RedirectType为External或者AliCDN时生效。
            //rule.getRedirect().setHttpRedirectCode(302);
            // 指定跳转时的域名,域名需符合域名规范。
            //rule.getRedirect().setHostName("oss.aliyuncs.com");
            // 指定跳转时的协议。只有设置RedirectType为External或者AliCDN时才生效。
            //rule.getRedirect().setProtocol(RoutingRule.Protocol.Https);
            // Redirect时Object名称将替换成ReplaceKeyWith指定的值,ReplaceKeyWith支持设置变量。
            //rule.getRedirect().setReplaceKeyWith("${key}.jpg");
            // 如果设置此字段为true,则Object的前缀将被替换为ReplaceKeyPrefixWith指定的值。
            rule.getRedirect().setEnableReplacePrefix(true);
            // Redirect时Object名称的前缀将替换成该值。
            rule.getRedirect().setReplaceKeyPrefixWith("examplebucket");
            // 是否检查回源body的MD5。只有设置RedirectType为Mirror时生效。
            rule.getRedirect().setMirrorCheckMd5(true);

            RoutingRule.MirrorHeaders mirrorHeaders = new RoutingRule.MirrorHeaders();
            // 是否透传除以下Header之外的其他Header到源站。只有设置RedirectType为Mirror时生效。
            mirrorHeaders.setPassAll(false);
            List passes = new ArrayList<String>();
            passes.add("cache-control");
            // 透传指定的Header到源站。只有设置RedirectType为Mirror时生效。
            mirrorHeaders.setPass(passes);
            List removes = new ArrayList<String>();
            removes.add("content-type");
            // 禁止透传指定的Header到源站。只有设置RedirectType为Mirror时生效。
            mirrorHeaders.setRemove(removes);
            List sets = new ArrayList<Map<String, String>>();
            Map header1 = new HashMap<String, String>();
            header1.put("Key", "key1");
            header1.put("Value", "value1");
            Map header2 = new HashMap<String, String>();
            header2.put("Key", "key2");
            header2.put("Value", "value2");
            sets.add(header1);
            sets.add(header2);
            // 设置传到源站的Header。不管请求中是否携带这些指定的Header,回源时都会设置这些Header。
            mirrorHeaders.setSet(sets);
            // 指定回源时携带的Header。只有设置RedirectType为Mirror时才生效。
            rule.getRedirect().setMirrorHeaders(mirrorHeaders);

            routingRules.add(rule);
            request.setRoutingRules(routingRules);
            ossClient.setBucketWebsite(request);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
# -*- coding: utf-8 -*-
import oss2
from oss2.models import BucketWebsite

# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# Endpoint以华东1(杭州)为例,其他Region请按实际情况填写。
# 填写Bucket名称,例如examplebucket。关于Bucket名称命名规范的更多信息,请参见Bucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

# 开启静态网站托管模式,并将默认首页设置为index.html,默认404页设置为error.html。
index_file = 'index.html'
error_file = 'error.html'
# 设置匹配的条件。
condition1 = Condition(key_prefix_equals='examplefolder',
                       http_err_code_return_equals=404)

# 指定镜像回源时携带的Header。
mirror_headers_set_1 = MirrorHeadersSet("myheader-key5","myheader-value5")
mirror_headers_set_2 = MirrorHeadersSet("myheader-key6","myheader-value6")
set_list = [mirror_headers_set_1, mirror_headers_set_2]
pass_list = ['myheader-key1', 'myheader-key2']
remove_list = ['myheader-key3', 'myheader-key4']
mirror_header = RedirectMirrorHeaders(pass_all=True, pass_list=pass_list, remove_list=remove_list, set_list=set_list)
# 指定匹配此规则后执行的动作。

redirect1 = Redirect(redirect_type=REDIRECT_TYPE_MIRROR, mirror_url='https://www.example.com/',
                     mirror_pass_query_string=True, mirror_follow_redirect=True, mirror_check_md5=True, mirror_headers=mirror_header)

rule1 = RoutingRule(rule_num=1, condition=condition1, redirect=redirect1)

# 设置镜像回源。
website_set = BucketWebsite(index_file, error_file, [rule1])
package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创建OSSClient实例。
    // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 填写Bucket名称,例如examplebucket。
    bucketName := "examplebucket"
    putXml := `<WebsiteConfiguration>
      <IndexDocument>
        <Suffix>index.html</Suffix>
        <SupportSubDir>true</SupportSubDir>
        <Type>0</Type>
      </IndexDocument>
      <ErrorDocument>
        <Key>error.html</Key>
        <HttpStatus>404</HttpStatus>
      </ErrorDocument>
      <RoutingRules>
        <RoutingRule>
          <RuleNumber>1</RuleNumber>
          <Condition>
            <! --只有匹配此前缀的Object才能匹配此规则。-->
            <KeyPrefixEquals>examplefolder/</KeyPrefixEquals>
            <! --访问指定Object时,返回status 404才能匹配此规则。-->
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
          </Condition>
          <Redirect>
            <! --指定跳转的类型。-->
            <RedirectType>Mirror</RedirectType>
            <PassQueryString>true</PassQueryString>
            <! --指定镜像回源的源站地址。本示例中指定为https://www.example.com/。-->
            <MirrorURL>http://example.com/</MirrorURL>-->           
            <! --指定执行跳转或者镜像回源规则时,是否携带请求参数。-->
            <PassQueryString>true</PassQueryString>
            <! --与PassQueryString作用相同,优先级高于PassQueryString。只有设置RedirectType为Mirror时生效。-->
            <MirrorPassQueryString>true</MirrorPassQueryString>
            <! --指定跳转时返回的状态码。只有设置RedirectType为External或者AliCDN时生效。-->
            <HttpRedirectCode>302</HttpRedirectCode>
            <! --指定跳转时的域名,域名需符合域名规范。-->
            <HostName>oss.aliyuncs.com</HostName>
            <! --指定跳转时的协议。只有设置RedirectType为External或者AliCDN时才生效。-->
            <Protocol>https</Protocol>
            <! --Redirect时Object名称将替换成ReplaceKeyWith指定的值,ReplaceKeyWith支持设置变量。-->
            <ReplaceKeyWith>key.jpg</ReplaceKeyWith>
            <! --如果设置此字段为true,则Object的前缀将被替换为ReplaceKeyPrefixWith指定的值。-->
            <EnableReplacePrefix>true</EnableReplacePrefix>
            <! --Redirect时Object名称的前缀将替换成该值。-->
            <ReplaceKeyPrefixWith>examplebucket</ReplaceKeyPrefixWith>
            <! --是否检查回源body的MD5。只有设置RedirectType为Mirror时生效。-->
            <MirrorCheckMd5>false</MirrorCheckMd5>
            <! --如果镜像回源获取的结果为3xx,是否继续跳转到指定的Location获取数据。 只有设置RedirectType为Mirror时才生效。-->
            <MirrorFollowRedirect>true</MirrorFollowRedirect>
            <MirrorHeaders>
              <! --是否透传除以下Header之外的其他Header到源站。只有设置RedirectType为Mirror时生效。-->
              <PassAll>true</PassAll>
              <! --透传指定的Header到源站。只有设置RedirectType为Mirror时生效。-->
              <Pass>myheader-key1</Pass>
              <Pass>myheader-key2</Pass>
              <! --禁止透传指定的Header到源站。只有设置RedirectType为Mirror时生效。-->
              <Remove>myheader-key3</Remove>
              <Remove>myheader-key4</Remove>
               <! --设置一个Header传到源站,不管请求中是否携带这些指定的Header,回源时都会设置这些Header。-->
              <Set>
                <Key>myheader-key5</Key>
                <Value>myheader-value5</Value>
              </Set>
            </MirrorHeaders>
          </Redirect>
        </RoutingRule>
      </RoutingRules>
    </WebsiteConfiguration>    `

    err = client.SetBucketWebsiteXml(bucketName,putXml)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}                    

使用命令行工具ossutil

关于使用ossutil配置镜像回源规则的具体操作,请参见添加或修改Website配置

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketWebsite