架構
go-faas 模組、資料流與執行生命週期總覽。
系統概覽
graph TB
Client[HTTP 客戶端] -->|POST /upload| Upload[Upload Handler]
Client -->|POST /run/*path| Run[Run Handler]
Client -->|POST /run-now| RunNow[RunNow Handler]
Upload --> Redis[(Redis)]
Run --> Redis
Run --> Sandbox[沙箱]
RunNow --> Sandbox
Sandbox --> Response[JSON / SSE]
Response --> Client
元件
| 元件 | 套件 | 職責 |
|---|---|---|
| Entry | cmd/api |
載入環境變數、檢查相依、初始化 Redis 與 slice、提供 HTTP |
| Router | internal |
Gin 引擎、路由、HTTP_PORT |
| Handler | internal/handler |
上傳、Run、RunNow、SSE |
| Database | internal/database |
Redis meta、程式碼、版本集合 |
| Sandbox | internal/sandbox |
各平台隔離指令 |
| Checker | internal/checker |
Runtime 相依檢查 |
| Utils | internal/utils |
帶預設值的環境變數讀取 |
啟動順序
cmd/api/main.go 依序執行:
godotenv.Load()(找不到.env時警告並繼續)checker.CheckPackage()— Linux 可能安裝缺失工具;darwin 為 no-opdatabase.Init()— ping Redis,失敗則結束sandbox.NewSlice()— Linux 建立 systemd user slice(失敗僅警告)internal.CreateServer()— 監聽至 SIGINT / SIGTERM,再以 5 秒 graceful shutdown
路由
CreateServer 建立 gin.Default(),綁定:
POST /upload→handler.UploadPOST /run/*targetPath→handler.RunPOST /run-now→handler.RunNow
監聽位址為 :{HTTP_PORT}(預設 8080)。
Handler 流程
graph TB
subgraph Handler
Upload[Upload] --> DBAdd[database.Add]
Run[Run] --> DBGet[database.Get]
Run --> RunCore[run]
RunNow[RunNow] --> RunCore
RunCore -->|stream=false| RunScript[runScript]
RunCore -->|stream=true| RunSSE[runScriptWithSSE]
RunScript --> SandboxCmd[sandbox.SandboxCommand]
RunSSE --> SandboxCmd
end
- Upload 驗證 path(不得含
..)、language,並以 Redis pipeline 儲存。 - Run 依 path 與可選
version載入程式碼後執行。 - RunNow 需
code+ 支援的language,不經 Redis。 - 共用
run()依stream選擇 JSON(runScript)或 SSE(runScriptWithSSE)。
資料庫 Key
path 經 MD5 雜湊。Key 如下:
| Key | 型別 | 內容 |
|---|---|---|
meta:{hash} |
Hash | path、language、latest |
code:{hash}:{ts} |
String | 程式碼 |
meta:{hash}:version |
Set | 版本時間戳 |
Get 在 version=0 時使用 latest。
沙箱
- Linux:
systemd-run --slice=go-faas-slice→bwrap(namespace、cap-drop ALL、無網路)→ 語言 wrapper - darwin:
sandbox-execseatbelt profile → wrapper
Wrapper 位於 internal/resource/(wrapper.py、wrapper.js、wrapper.ts),讀取 stdin JSON {payload},提供 event / input,並將回傳值以 JSON 印出。
狀態機
stateDiagram-v2
[*] --> Idle
Idle --> Preparing: 收到 Run / RunNow
Preparing --> Running: 啟動沙箱行程
Running --> Streaming: stream=true
Running --> Completed: 正常結束
Streaming --> Completed: 送出 result
Running --> Failed: 逾時 / stderr / 非零退出
Streaming --> Failed: 客戶端中斷 / 錯誤
Failed --> Idle
Completed --> Idle