跳轉到

資料層與網路

資料層完全採用受管理服務——沒有自建資料庫、沒有需要修補的 Redis 叢集、沒有需要調校的連線池。ElastiCache Valkey Serverless 處理所有即時狀態,Aurora PostgreSQL 儲存持久性資料,RDS Proxy 吸收來自短暫 ECS Task 的連線波動。

持久性與可用性

Aurora PostgreSQL:儲存空間自動增長(10 GB 至 128 TB),Multi-AZ 故障切換 < 30 秒(1K 使用者時啟用),讀取複本延遲 < 20ms。Valkey Serverless:從 1 GB / 1K ECPU 自動擴展至 10 GB / 100K ECPU,零需干預;非交易時段成本降至儲存最低費用。RDS Proxy:將數百個短暫 ECS Task 連線多工為約 50 個持久化資料庫連線,防止規模化時連線池耗盡。


ElastiCache Valkey Serverless

Valkey(Redis 相容)作為平台的即時神經系統。每一個亞秒級互動——Worker 心跳、訂單路由、工作階段管理——都透過它流轉。

儲存的資料

資料類型 鍵模式 (Key Pattern) TTL 用途
Worker 心跳標記 worker:active:{user_id} 30s 存活偵測。Worker 每 5 秒重新整理。
請求佇列 trading:user:{user_id}:requests 基於 BLPOP 的工作佇列。Worker 即時取出訂單。
回應信箱 trading:response:{request_id} 60s API 在提交訂單後輪詢 Worker 的回應。
控制訊息 worker:control:{user_id}:messages 無需重啟即可重新載入憑證的命令。
Worker 中繼資料 worker:metadata:{user_id} 30s Task ARN、執行個體 ID、啟動時間。
工作階段資料 session:{session_id} 24h 使用者工作階段令牌和 CSRF 狀態。
Webhook 重送雜湊 webhook:replay:{hash} 5min 冪等性——拒絕重複的 Webhook 投遞。
速率限制計數器 ratelimit:{user_id}:{endpoint} Window 逐使用者逐端點的滑動視窗速率限制。
ECS Task 快取 ecs:tasks:cache 90s 快取 ECS Task 列表以避免 API 節流。
標的快取 symbols:{broker}:{exchange} 1h 券商標的/合約資料。避免重複 API 呼叫。

擴展配置

參數 最小值 最大值 擴展方式
儲存空間 1 GB 10 GB 自動
運算 1,000 ECPU 100,000 ECPU 自動

為什麼選擇 Serverless 而非佈建式

交易平台的流量變異極大。在交易時段(台灣市場 09:00-13:30),數千個 Worker 每 5 秒發送心跳,訂單持續流入。收盤後,流量降至接近零。佈建式 ElastiCache 需要按尖峰配置並全天候付費。Valkey Serverless 的 ECPU 隨需求擴展——非交易時段成本降至僅有儲存最低費用。

定價模型

Valkey Serverless 按兩個維度計費:

  • 儲存空間:$0.125/GB-小時
  • ElastiCache 處理單元 (ECPU):每 ECPU $0.0000098

一個 ECPU 大約對應一個對小於 1 KB 資料的簡單命令。對較大 payload 或複雜操作(SORT、LRANGE 對長列表)的命令會按比例消耗更多 ECPU。


RDS Aurora PostgreSQL

Aurora PostgreSQL 是所有持久性資料的記錄系統 (system of record)。所有需要在重啟後存活的資料都儲存在這裡。

儲存的資料

表格 / 領域 行數估算(10K 使用者) 用途
users 10K 使用者帳號、偏好設定、訂閱方案
trading_accounts 30K(平均每使用者 3 個) 券商憑證(AES-256-GCM 加密)、帳戶配置
orders 每月 1M+ 訂單歷史、狀態、成交、時間戳記
audit_logs 每月 5M+ 每個已驗證操作的 IP、user-agent、路徑
sessions 10K 活躍 伺服器端工作階段儲存
api_keys 15K 每個交易帳戶的 Webhook 令牌、API 金鑰
subscription_plans 約 10 方案定義、功能開關、限制

擴展層級

使用者數 執行個體 配置 估算成本
1-500 db.t3.large 單一執行個體,每日快照 約 $120/月
500-1K db.t3.large Multi-AZ 待命 約 $240/月
1K-5K db.r6g.large Multi-AZ + 每日快照,增強監控 約 $400/月
5K-10K db.r6g.xlarge Multi-AZ + 1 個讀取複本 約 $800/月
10K-50K db.r6g.2xlarge Multi-AZ + 2 個讀取複本 約 $1,800/月
50K+ db.r6g.4xlarge Multi-AZ + 2 個讀取複本 + 佈建 IOPS 約 $4,000/月

Aurora 的優勢

Aurora 的儲存空間從 10 GB 自動增長到 128 TB,無需停機。複本延遲通常 < 20ms。故障切換到待命複本在 30 秒內完成。


RDS Proxy

ECS Task 是短暫的——Worker 隨著使用者上線和離開而不斷啟動和停止。如果沒有連線池,每個 Task 開啟一個 PostgreSQL 連線會產生顯著開銷(TLS 握手、身份驗證、資料庫端的記憶體分配)。

為什麼需要 RDS Proxy

問題 無 Proxy 有 Proxy
連線波動 每個 Task 新建 TCP + TLS 在持久化連線池上多工
連線上限 db.t3.large 最多約 680 個連線 應用程式端看到無限;Proxy 管理連線池
故障切換 應用程式必須偵測並重連 Proxy 透明處理
憑證輪換 需要重啟應用程式 Proxy 從 Secrets Manager 取得新憑證

配置

參數
最大連線數 資料庫最大值的 80%
借用逾時 120 秒
閒置逾時 1800 秒
引擎 PostgreSQL
身份驗證 Secrets Manager(支援自動輪換)

Proxy 將應用程式連線(可能來自數百個 ECS Task)多工到較少的資料庫連線集,跨請求重複使用。這在規模化時至關重要——每個執行個體 30 個 Worker x 10 個執行個體 = 300 個潛在連線,但資料庫透過 Proxy 只看到約 50 個活躍連線。


VPC 架構

flowchart LR subgraph public["公有子網路(AZ-a, AZ-b)"] ALB["ALB"] API["API 任務"] W["Worker 任務"] end subgraph private["私有子網路(AZ-a, AZ-b)"] Proxy["RDS Proxy"] RDS["Aurora 主要 + 待命"] Valkey["Valkey 端點"] Lambda["Lambda ENI"] end Internet["網際網路"] --> ALB --> API W -->|"券商 API"| Internet API & W --> Proxy --> RDS API & W & Lambda --> Valkey

為什麼 Worker 需要公有子網路

Worker 必須透過公共網路存取外部券商 API(Shioaji、Fubon)。將它們放在私有子網路中需要 NAT Gateway——每個可用區域 $0.045/小時加上每 GB 處理 $0.045。對於產生大量對外流量的交易平台,NAT 成本會超過 EC2 執行個體成本。使用公有子網路搭配限制入站流量的安全群組,可以在零額外成本下達到相同的安全態勢。

安全群組規則

規則 來源 目的地 連接埠 協定
ALB → API ALB SG API SG 8000 TCP
API → Valkey API SG Valkey SG 6379 TCP
Worker → Valkey Worker SG Valkey SG 6379 TCP
Lambda → Valkey Lambda SG Valkey SG 6379 TCP
API → RDS Proxy API SG RDS SG 5432 TCP
Worker → RDS Proxy Worker SG RDS SG 5432 TCP
Worker → Internet Worker SG 0.0.0.0/0 443 TCP(出站)
API → Internet API SG 0.0.0.0/0 443 TCP(出站)

最小權限

沒有安全群組允許 0.0.0.0/0 入站。ALB 安全群組只接受來自網路的 80/443。API Task 只接受來自 ALB 安全群組的 8000。Worker 不接受任何入站——所有通訊都是對外到 Redis 和券商 API。


ALB + WAF

應用程式負載均衡器 (Application Load Balancer)

參數
模式 面向網際網路 (Internet-facing)
TLS ACM 管理的憑證(自動續約)
健康檢查路徑 /health
健康檢查間隔 15 秒
健康閾值 連續 2 次通過
不健康閾值 連續 3 次失敗
註銷延遲 120 秒
閒置逾時 60 秒

WAF 規則

規則 類型 配置 用途
管理員 IP 限制 IP Set 管理員 IP 白名單 阻擋來自未知 IP 的管理面板存取
TradingView IP 豁免 IP Set TradingView Webhook 來源 IP 繞過合法 Webhook 的速率限制
登入速率限制 基於速率 每 IP 每 5 分鐘 100 個請求 防止對身份驗證端點的暴力攻擊
全域速率限制 基於速率 每 IP 每 5 分鐘 2000 個請求 通用 DDoS 防護
AWS 託管 — SQLi 託管規則群組 AWSManagedRulesSQLiRuleSet SQL 注入防護
AWS 託管 — XSS 託管規則群組 AWSManagedRulesCommonRuleSet 跨站腳本攻擊、惡意輸入
AWS 託管 — IP 信譽 託管規則群組 AWSManagedRulesAmazonIpReputationList 阻擋已知惡意 IP

TradingView IP 豁免

TradingView 從一組已知的 IP 範圍發送 Webhook。這些 IP 免於速率限制,但仍通過 SQLi/XSS 規則。如果 TradingView 變更其 IP 範圍,Webhook 將被速率限制,直到 IP 集更新為止。


其他服務

KMS — 金鑰管理

參數
金鑰類型 RSA-4096,非對稱
後端 HSM(硬體安全模組)
用途 包裹逐使用者 AES-256-GCM 資料加密金鑰
輪換 自動年度輪換

每個交易帳戶的券商憑證都使用唯一的 AES-256-GCM 金鑰加密。該 AES 金鑰本身使用 KMS RSA 主金鑰加密(包裹)。解密需要加密的資料金鑰(儲存在資料庫中)和 KMS 存取權限(由 IAM 政策控制)。僅竊取資料庫不會暴露任何資訊。

Secrets Manager

儲存應用程式配置:資料庫憑證、API 密鑰、加密參數。由 ECS Task 定義和 Lambda 函式在啟動時參照。支援自動輪換。

ECR — 容器映像檔倉庫

倉庫 用途 生命週期
shioaji-api API 容器映像檔(FastAPI + Gunicorn) 保留最近 10 個標記映像檔
shioaji-worker Worker 容器映像檔(券商 SDK) 保留最近 10 個標記映像檔

映像檔在 CI/CD 中建構、掃描漏洞,並推送到 ECR。ECS 在 Task 啟動時從 ECR 拉取。

Route 53

4pass.io 的 DNS 管理。A 記錄別名指向 ALB。健康檢查與 ALB 健康狀態整合。

VPC 端點 — Lambda

參數
類型 介面端點 (Interface endpoint)
服務 com.amazonaws.{region}.elasticache
可用區域 3 個(與 Lambda 子網路匹配)

Lambda 函式在 VPC 內運行以存取 Valkey。VPC 端點提供私有連線,無需透過網際網路路由,降低延遲並提升安全性。