使用 Cloudflare Workers 加速 Oracle Cloud 对象存储

Intro

Oracle Cloud 是由甲骨文驱动的公有云产品,其 Free Tier 计划包含了 20GB 的对象存储服务。由于其可用区位于海外,跨境访问对象存储时用户体验很不理想。我们可以使用 Cloudflare Workers 搭建反向代理,并配合缓存以节省开销。

Passthrough

直通模式下,Cloudflare Workers 直接转发请求和响应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const REGION = "";
const BUCKET = "";
const NAMESPACE = "";

const BUCKET_URL = `https://objectstorage.${REGION}.oraclecloud.com/n/${NAMESPACE}/b/${BUCKET}/o`;

addEventListener("fetch", (event) => {
event.respondWith(handle(event));
});

async function handle(event) {
const pathname = new URL(event.request.url).pathname;
return fetch(`${BUCKET_URL}${pathname}`);
}

Cache

缓存模式下,先使用 Cache API 将请求缓存于 Cloudflare 的 CDN ,再返回响应正文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const REGION = "";
const BUCKET = "";
const NAMESPACE = "";

const BUCKET_URL = `https://objectstorage.${REGION}.oraclecloud.com/n/${NAMESPACE}/b/${BUCKET}/o`;

addEventListener("fetch", (event) => {
event.respondWith(handle(event));
});

async function handle(event) {
let request = event.request;

if (["GET", "HEAD", "OPTIONS"].includes(request.method)) {
const pathname = new URL(request.url).pathname;
const cache = caches.default;

let response;
if (request.method === "GET") {
// 缓存 GET 请求
response = await cache.match(request);
if (!response) {
response = await fetch(`${BUCKET_URL}${pathname}`);
let headers = Object.fromEntries(new Map(response.headers));
headers["cache-control"] = "public, max-age=14400";
response = new Response(response.body, { ...response, headers });
event.waitUntil(cache.put(request, response.clone()));
}
} else {
// 将非 GET 请求直接转发
response = fetch(`${BUCKET_URL}${pathname}`, { method: request.method });
}

// override 错误信息以避免泄露 bucket 名称
if (response.status === 404)
return new Response("Not found", { status: 404 });

// 允许浏览器直接播放 .mp4 文件而不触发下载
if (pathname.endsWith(".mp4")) {
headers = { "Content-Type": "video/mp4" };
response = new Response(response.body, { ...response.body, headers });
}
return response;
} else {
return new Response("Method not allowed", { status: 405 });
}
}

Eval

  • Before: 从境内直连对象存储,下载速度约为 50KB/s。
  • After: 在未使用自选 Cloudflare IP 的前提下,下载速度可达 6MB/s,提升 60~120x。

Ref