全部產品
Search
文件中心

Object Storage Service:鏡像回源

更新時間:Nov 13, 2024

在存量資料移轉完成後,您可以配置鏡像回源,以確保使用者可以訪問到尚未遷移至OSS的增量資料,以避免對業務的影響。配置鏡像回源後,當要求者訪問Bucket中不存在的檔案(Object)時,OSS會根據回源規則指定的來源站點擷取該檔案。OSS擷取到目標檔案後,會將檔案返回給要求者並儲存到Bucket中。

使用限制

  • 支援地區

    華東1(杭州)、華東2(上海)、華北1(青島)、華北2(北京)、華北 3(張家口)、華北5(呼和浩特)、華北6(烏蘭察布)、華南1(深圳)、華南2(河源)、華南3(廣州)、西南1(成都)、中國香港、美國(矽谷)、美國(維吉尼亞)、日本(東京)、新加坡、馬來西亞(吉隆坡)、印尼(雅加達)、菲律賓(馬尼拉)、德國(法蘭克福)、英國(倫敦)、阿聯酋(杜拜)地區支援配置鏡像回源。

  • 規則數量

    回源規則最多配置20條,按RuleNumber的先後順序依次匹配。如果命中當前規則,則後續規則不再匹配。規則未命中表示沒有匹配回源條件,與回源後是否成功擷取目標檔案無關。

  • QPS和流量限制

    單個阿里雲帳號在中國內地各地區預設QPS為2000、流量為2 Gbit/s;非中國內地各地區預設QPS為1000、流量為1 Gbit/s。

    如果您的業務有更大的QPS或者流量需求,請聯絡支援人員

  • 回源地址

    回源地址不支援內網地址。

  • 預設逾時時間

    鏡像回源預設逾時時間為10秒。

使用情境

鏡像回源主要用於資料無縫遷移到OSS的情境。例如某服務已經在自己建立的來源站點或者在其他雲產品上運行。現因業務發展,需要將資料移轉到OSS上,但是又不能停止服務,此時可以在遷移資料的同時,使用鏡像回源功能保證業務的正常進行。關於使用案例的更多資訊,請參見互連網公司業務無縫遷移至阿里雲OSS

說明

OSS鏡像回源不產生額外的費用,但是這個請求本身需照常收費。計費規則與非鏡像回源請求一樣收費。更多資訊,請參見請求費用

回源流程

鏡像回源具體流程如下圖所示。

image

回源規則

  • 回源規則引發條件

    只有當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給使用者。

  • 回源檔案更新規則

    若某個檔案已經通過鏡像回源到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,第三列設定為空白。

  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.common.auth.*;
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";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        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, MirrorHeadersSet, RedirectMirrorHeaders, Redirect, RoutingRule, \
    REDIRECT_TYPE_MIRROR, Condition
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Endpoint以華東1(杭州)為例,其他Region請按實際情況填寫。
# 填寫Bucket名稱,例如examplebucket。
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])

# 設定鏡像回源。
bucket.put_bucket_website(website_set)
package main

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

func main() {
	// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 建立OSSClient執行個體。
	// yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 填寫Bucket名稱,例如examplebucket。
	bucketName := "examplebucket"

	var indexWebsite = "myindex.html"
	var errorWebsite = "myerror.html"

	btrue := true
	bfalse := false
	// 指定回源類型為鏡像。
	ruleOk := oss.RoutingRule{
		RuleNumber: 1,
		Condition: oss.Condition{
			KeyPrefixEquals: "",
			// 指定回源條件為HTTP狀態代碼404。
			HTTPErrorCodeReturnedEquals: 404,
		},
		Redirect: oss.Redirect{
			RedirectType: "Mirror",
			// PassQueryString: &btrue,
			// 指定回源地址。
			MirrorURL: "http://www.test.com/",
			// MirrorPassQueryString:&btrue,
			// MirrorFollowRedirect:&bfalse,
			// MirrorCheckMd5:&bfalse,
			MirrorHeaders: oss.MirrorHeaders{
				// PassAll:&bfalse,
				// 允許傳遞指定HTTP Header參數。
				Pass: []string{"myheader-key1", "myheader-key2"},
				// 禁止傳遞指定HTTP Header參數。
				Remove: []string{"myheader-key3", "myheader-key4"},
				Set: []oss.MirrorHeaderSet{
					{
						Key:   "myheader-key5",
						Value: "myheader-value5",
					},
				},
			},
		},
	}

	// 指定回源類型為重新導向。
	ruleArrOk := []oss.RoutingRule{
		{
			RuleNumber: 2,
			Condition: oss.Condition{
				// 指定回源條件為HTTP狀態代碼404,檔案名稱首碼為abc/。
				KeyPrefixEquals:             "abc/",
				HTTPErrorCodeReturnedEquals: 404,
				IncludeHeader: []oss.IncludeHeader{
					{
						Key:    "host",
						Equals: "test.oss-cn-beijing-internal.aliyuncs.com",
					},
				},
			},
			Redirect: oss.Redirect{
				RedirectType:     "AliCDN",
				Protocol:         "http",
				HostName:         "www.test.com",
				PassQueryString:  &bfalse,
				ReplaceKeyWith:   "prefix/${key}.suffix",
				HttpRedirectCode: 301,
			},
		},
		// 指定回源類型為鏡像。
		{
			RuleNumber: 3,
			Condition: oss.Condition{
				KeyPrefixEquals:             "",
				HTTPErrorCodeReturnedEquals: 404,
			},
			Redirect: oss.Redirect{
				RedirectType:          "Mirror",
				PassQueryString:       &btrue,
				MirrorURL:             "http://www.test.com/",
				MirrorPassQueryString: &btrue,
				MirrorFollowRedirect:  &bfalse,
				MirrorCheckMd5:        &bfalse,
				MirrorHeaders: oss.MirrorHeaders{
					PassAll: &btrue,
					Pass:    []string{"myheader-key1", "myheader-key2"},
					Remove:  []string{"myheader-key3", "myheader-key4"},
					Set: []oss.MirrorHeaderSet{
						{
							Key:   "myheader-key5",
							Value: "myheader-value5",
						},
					},
				},
			},
		},
	}

	wxmlOne := oss.WebsiteXML{
		IndexDocument: oss.IndexDocument{
			Suffix: indexWebsite,
		},
		ErrorDocument: oss.ErrorDocument{
			Key: errorWebsite,
		},
	}
	wxmlOne.RoutingRules = append(wxmlOne.RoutingRules, ruleOk)
	wxmlOne.RoutingRules = append(wxmlOne.RoutingRules, ruleArrOk...)
	err = client.SetBucketWebsiteDetail(bucketName, wxmlOne)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

     

使用命令列工具ossutil

關於使用ossutil配置鏡像回源規則的具體操作,請參見添加或修改Website配置

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見PutBucketWebsite

相關文檔

您可以通過日誌查詢通過回源上傳的檔案。具體操作,請參見即時日誌查詢