iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0

前言

在眾多雲端服務中,鮮少會一開始註冊會員後,就要求玩家課金,畢竟你還不知道這個網站或線上服務,能夠給你帶來什麼功能。 適度地提供免費額度,讓會員試用是常態了! 然而,如果這個免費沒有加以限制,很快就會變成試探人性極限的翻車現場。 接著我們會來嘗試,避免那些可能會讓費用暴增的風險,要來限制免費額度哩。

作法探討

  • 因為我們大量使用了 S3 作為存放各個會員影片檔案的基礎,所以很明確就是要限制各個會員總量啦! 假設我們預計先提供每個帳號 500M 為例。
  • 然而,S3 本身不支援「每個目錄容量上限」的內建功能。 嚴格來說,S3 是物件儲存,不是真的有「資料夾」。
  • 所以,應該要觸發造成 S3 儲存資料異動的時候,去計算特定路徑的總容量。

計算大小

  • 先來寫一段程式,計算看看 alex 的存放大小
import boto3

s3 = boto3.client("s3")

def get_prefix_size(bucket, prefix):
    total_size = 0
    continuation_token = None

    while True:
        kwargs = {"Bucket": bucket, "Prefix": prefix}
        if continuation_token:
            kwargs["ContinuationToken"] = continuation_token

        resp = s3.list_objects_v2(**kwargs)
        for obj in resp.get("Contents", []):
            total_size += obj["Size"]

        if resp.get("IsTruncated"):  # 有下一頁
            continuation_token = resp["NextContinuationToken"]
        else:
            break

    return total_size

# 範例:計算 alex 的 videos 總容量
bucket_name = "exsky-backup-media"
prefix = "alex/videos/"
size_bytes = get_prefix_size(bucket_name, prefix)
print(f"{prefix} 已使用 {size_bytes/1024/1024:.2f} MB")

輸出如下

  • python count_s3_size.py
    alex/videos/ 已使用 428.31 MB

每日監控任務

  • 每天用 AWS EventBridge (排程事件) 觸發 Lambda
  • Lambda 對每個使用者的 prefix 呼叫上面那段程式碼
  • 把結果:
    • 寫入 DynamoDB(儲存歷史紀錄)
    • 發送 SNS 通知(若超過上限)
    • 或是更新 CloudWatch metric(方便畫圖)

阻擋超出限制使用者上傳的機制

  • S3 沒有辦法阻止上傳(沒有 per-prefix quota),但你可以透過應用層(API Gateway + Lambda)做出類似的行為:
    • 當使用者要上傳檔案前,前端呼叫 /generate-url。
    • Lambda 先呼叫 get_prefix_size(username/videos/) 計算目前使用量。
    • 若超過上限(例如 500 MB),就不回傳上傳 URL

結論

  • 釐清脈絡後,下一篇可以開始開發機制了!

上一篇
【Day 26】 降低營運成本 / 最佳化 S3 儲存效率
下一篇
【Day 28】 限制會員存放容量上限 (下)
系列文
無法成為片師也想拍 Vlog?!個人影音小工具的誕生!28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言