最危险的部署方式是直接在生产环境运行go run main.go,它绕过构建优化、忽略平台适配、暴露调试信息,且易致小内存设备oom;必须用go build配合goos/goarch/cgo_enabled=0等显式配置生成静态二进制。

直接在生产环境跑 go run main.go 是最常见也最危险的部署方式——它绕过了构建优化、忽略平台适配、暴露调试信息,还可能因内存缓存失控导致树莓派等小内存设备 OOM。
构建前必须显式指定 GOOS/GOARCH
即使你在树莓派上开发,也不能依赖本地默认构建。Go 的 go build 会隐式启用 CGO(尤其在有 net 或 os/user 等包时),导致二进制体积膨胀、启动变慢,甚至在无 libc 的容器中 panic。
- 树莓派 4/5(ARM64):用
GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o server . - x86_64 服务器:用
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o server . - 禁用 CGO(推荐):加
CGO_ENABLED=0,避免动态链接依赖,确保纯静态二进制
静态文件服务要关掉 CacheDuration
app.Static("/static", "./public") 在 Pi Zero 2W 或 1GB 内存设备上极易触发 OOM:Fiber 默认开启 10 秒内存缓存,加载多个 JS/CSS 后 RSS 内存可飙到 400MB+,内核直接 kill 进程。
- 安全写法:
app.Static("/static", "./public", fiber.Static{CacheDuration: 0}) - 若需缓存,改用 Nginx 或 Caddy 做前置静态服务,Fiber 只管 API
- 注意:
CacheDuration: 0不影响 HTTP 缓存头(ETag/Last-Modified),只关内存缓存
别用 fiber.Logger() 打日志到文件或 stdout
在 SD 卡或低 I/O 性能设备上,fiber.Logger() 高频写日志会拖垮整个服务,且日志格式不兼容 systemd journal,无法做结构化检索。
- 关闭默认日志:
app := fiber.New(fiber.Config{DisableStartupMessage: true}) - 用
log.Printf或结构化日志库(如zerolog)输出到 stderr,由 systemd 拦截管理 - 绝对不要在 handler 里调用
c.Locals()存日志上下文——fiber.Ctx是复用对象,跨请求读写会引发数据污染
TLS 绝对不要让 Fiber 自己扛
Fiber 的 app.Listen("0.0.0.0:443") 走纯软件 RSA 握手,在树莓派上首字节延迟常超 800ms,且不支持 OCSP Stapling 和 ALPN;Kubernetes 场景下更不该由应用层处理证书。
- 嵌入式方案:用
civetweb或nginx-light做反向代理,Fiber 只监听127.0.0.1:3000HTTP - K8s 方案:用
Ingress(Nginx / Traefik)终止 TLS,Service 指向 ClusterIP + NodePort - 证书更新必须走外部 reload,Fiber 不支持运行时热替换证书文件
真正容易被忽略的是 fiber.Ctx 的生命周期——它不是 request-scoped 的“新对象”,而是从池里取的复用实例。任何把 c.Params()、c.Body() 或 c.IP() 的返回值保存到 goroutine 外、或塞进 map/channel 的操作,都可能在下一个请求里读到脏数据。











