关于 tigris-egress-optimizer
这是一项用于诊断并降低 Tigris 对象存储过量流出流量费用的技能。它帮助开发者检查用量与代码模式,调整缓存和文件交付方式,再验证带宽变化。
主要功能
- 01检查存储桶带宽和对象大小
- 02查找高流量代码模式
- 03用元数据检查替代完整下载
- 04设置缓存头并直接交付文件
- 05持续验证带宽变化
适用场景
- 01调查异常偏高的存储传输费用
- 02减少静态资源的重复下载
- 03避免应用服务器代理对象下载
- 04交付更小的图像缩略图
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tigrisdata/ skills --skill tigris-egress-optimizer安装后在 Claude Code 中输入/tigris-egress-optimizer确认已加载。
附带文件metadata.jsonREADME.md
详细介绍
Tigris 出站流量优化器
诊断并解决存储出站流量(网络数据传输)成本过高的问题。按照这个 4 步框架识别反模式、应用修复方案并验证节省效果。
大多数高额出站流量账单都源于应用获取了超出实际使用量的数据,而非基础设施问题。
前提条件
在进行其他操作之前,如果尚未安装 Tigris CLI,请先安装:
tigris help || npm install -g @tigrisdata/cli
如果需要安装,请告知用户:“我正在安装 Tigris CLI(@tigrisdata/cli),以便我们使用 Tigris 对象存储。”
第 1 步:诊断
找出消耗带宽最多的存储桶和访问模式。
检查带宽指标
# Check bucket usage
tigris usage
# List objects by size (find large files being served frequently)
tigris ls t3://my-bucket --recursive -l | sort -k3 -rn | head -20
需要回答的问题
- 哪些存储桶的带宽最高?
- 是否反复下载大型文件?
- 对象是通过应用服务器访问,还是直接访问?
- 是否下载了用户从未看到的对象?
第 2 步:分析代码库
检查应用代码中是否存在以下常见反模式:
反模式检查清单
| 反模式 | 症状 | 影响 |
|---|---|---|
| 为获取元数据而下载完整对象 | 使用 get(),而 head() 就足够 | 高 — 下载整个文件 |
| 重新下载不可变资源 | 静态内容没有缓存层 | 高 — 反复消耗带宽 |
| 通过应用服务器代理 | 服务器下载后再向客户端提供 | 带宽翻倍(Tigris→服务器 + 服务器→客户端) |
| 缺少 Cache-Control 标头 | 浏览器每次加载页面时都会重新获取 | 非常高 — 随用户数量倍增 |
| 未使用 CDN | 公共内容存放在私有存储桶中 | 中 — 只有单一源站,没有边缘缓存 |
| 为缩略图下载完整对象 | 为显示 100px 的缩略图而获取 5MB 图片 | 高 — 数据量多出 50 倍 |
搜索代码
在代码库中查找以下模式:
# Downloads that should be head() calls
grep -rn "get(" --include="*.ts" --include="*.js" | grep -v "test"
# Missing cache headers on put()
grep -rn "put(" --include="*.ts" --include="*.js" | grep -v "cacheControl\|Cache-Control"
# Server-side file proxying
grep -rn "pipe\|stream\|createReadStream" --include="*.ts" --include="*.js"
第 3 步:修复
修复 1:使用 head() 代替 get() 获取元数据
// Before — downloads entire file just to check if it exists
const result = await get("avatars/user-123.jpg", "file");
if (result.error) console.log("not found");
// After — only fetches metadata (size, contentType, modified)
const result = await head("avatars/user-123.jpg");
if (result.error) console.log("not found");
console.log(result.data?.size, result.data?.contentType);
修复 2:添加 Cache-Control 标头
// Set cache headers on upload
await put("assets/logo.png", file, {
access: "public",
contentType: "image/png",
});
建议的缓存值:
| 内容类型 | Cache-Control |
|---|---|
| 带哈希的资源(JS、CSS) | public, max-age=31536000, immutable |
| 图片(头像、上传内容) | public, max-age=86400(1 天) |
| 动态内容 | private, no-cache |
| 字体 | public, max-age=31536000, immutable |
修复 3:使用公共存储桶搭配 CDN
Tigris 公共存储桶会自动从全球最近的边缘节点提供内容——无需单独设置 CDN。
# Make bucket public
tigris buckets create my-public-assets --public
# Or update existing bucket
tigris buckets update my-bucket --public
公共存储桶 URL 由 Tigris 的全球边缘网络提供。对于基本的静态资源分发,这样就无需使用 CloudFront、Cloudflare 或其他 CDN 层。
修复 4:使用预签名 URL(跳过服务器代理)
// Before — server downloads file, then sends to client (2x egress)
app.get("/download/:path", async (req, res) => {
const result = await get(req.params.path, "stream");
result.data.pipe(res);
});
// After — redirect client to download directly from Tigris (1x egress)
app.get("/download/:path", async (req, res) => {
const result = await getPresignedUrl(req.params.path, {
operation: "get",
expiresIn: 300,
});
res.redirect(result.data!.url);
});
修复 5:单独存储缩略图
// Before — serving 5MB original for a 100px avatar
<img src="/api/files/avatars/user-123.jpg" width="100" />
// After — generate and store thumbnail on upload
import sharp from "sharp";
const thumb = await sharp(originalBuffer)
.resize(100, 100, { fit: "cover" })
.jpeg({ quality: 80 })
.toBuffer();
await put("avatars/user-123-thumb.jpg", thumb, {
access: "public",
contentType: "image/jpeg",
});
// Serve the 5KB thumbnail instead of the 5MB original
修复 6:使用 ETag 进行客户端缓存
// Server returns ETag on first request
app.get("/api/config", async (req, res) => {
const result = await head("config/app.json");
const etag = result.data?.modified?.toISOString();
if (req.headers["if-none-match"] === etag) {
return res.status(304).end(); // No body sent, no egress
}
const file = await get("config/app.json", "string");
res.set("ETag", etag);
res.json(JSON.parse(file.data));
});
修复 7:区域固定
让数据靠近计算资源,以减少跨区域传输:
# Pin bucket to specific regions
tigris buckets create my-bucket --locations us-east-1,eu-west-1
第 4 步:验证
应用修复后:
- 监控带宽 — 在 Tigris 控制面板中检查带宽是否下降
- 比较前后情况 — 跟踪 1–2 周的带宽
- 设置警报 — 配置监控,以便发现意外的带宽激增
- 定期检查 — 新功能可能会引入新的反模式
快速见效方案摘要
| 修复方案 | 工作量 | 影响 |
|---|---|---|
| 添加 Cache-Control 标头 | 低 | 高 |
| 切换到公共存储桶(CDN) | 低 | 高 |
| 使用预签名 URL 代替代理 | 中 | 高 |
检查时用 head() 替代 get() | 低 | 中 |
| 单独存储缩略图 | 中 | 高 |
| 区域固定 | 低 | 中 |
重要规则
始终: 使用公共存储桶提供用户内容 | 每次上传都设置 Cache-Control 标头 | 使用预签名 URL 下载私有文件 | 使用 head() 检查文件是否存在及其元数据
切勿: 在预签名 URL 可用时通过应用服务器代理文件 | 缩略图足够时仍提供原始图像 | 对不可变资源跳过缓存 | 忽略带宽指标
相关技能
- tigris-image-optimization — 生成缩略图和变体
- tigris-static-assets — 通过 CDN 和缓存标头分发内容
- tigris-lifecycle-management — 将冷数据移至成本更低的层级
官方文档
评论
支持 Markdown